The error must be so tiny in these few lines that I will not get it myselft.
Here is my code:
askName = do
putStr "Type your name: "
name <- getLine
return name
sayHelloTo name = do
when (null name) (name <- askName)
Apparently it gives an error:
1 of 1] Compiling Main ( test.hs, interpreted )
test.hs:9:30: parse error on input `<-'
Failed, modules loaded: none.
Any suggestion?
Edit 1.
Same if I write:
sayHelloTo name = do
when (null name) (name2 <- askName)
The
name2 <-syntax is part of do-notation and can only be used inside adoblock. It is also not a variable assignment – under the hood it is just creating a callback function that hasname2as a parameterThat is, the following code:
desugars into
I hope this helps make it clear that you don’t assign things or mutate them in Haskell.
anyway, to solve your particular problem, whay you could do is just use if-then-else (something that is actually equivalent to the
?:ternary oerator) and return the appropriate value. For example, the following function uses recursion to ask for a name again and again until it is happy with the resultor, without the do notation sugar:
This might be a bit moe different the what you are used to, but I guess you should be able to clear thing sup after you get how this is working. Basically
getNonEmptyNameis of typeIO String, meaning it is an IO actioin IO action that yields a String when it is run. The if-then-else part is supposed to evaluate to anIO Stringvalue as well, since its value will be the return value of getNonEmptyName. This all works all right since in the first we do a recursive call to getNonEmptyName (and that gives an IP String value as desired) and in the else branch we promote a regular string value (name) to an IO String using the return function.