On Fri, May 31, 2013 at 5:02 PM, Miro Karpis <miroslav.karpis@gmail.com> wrote:
Please, I'm trying to do some user user input validation, but it looks like my  approach is not correct. Here is my code:

textInput :: IO ()
textInput
| dataIn == "bye" = return () 
| otherwise          = textInput
where dataIn <- getLine

the idea is that when user inputs "bye" the program should end/return. Problem is that I'm getting 'parse error on input `<-'' error. How can I achieve it?

Another question I have is: how can I have more actions in guard, when the condition is valid. Something like (write on IO + return if dataIn == "bye):

textInput :: IO ()
textInput
| dataIn == "bye" = (puStrLn "quitting", return () ) -- 
| otherwise          = textInput
where dataIn <- getLine

Millions of thanks for any kind of input..

Your initial attempt didn't work because the "foo <- bar" syntax is only available when using a "do block"

A straightforward way to do this without "do block" syntax may look something like this:

textInput :: IO ()
textInput = getLine >>= go
  where
    go dataIn
      | dataIn == "bye" = putStrLn "quitting" >> return ()
      | otherwise       = textInput

Note that putStrLn actually returns IO (), which is the same thing as return (), so it is redundant. You can shorten it to this:

textInput :: IO ()
textInput = getLine >>= go
  where
    go dataIn
      | dataIn == "bye" = putStrLn "quitting"
      | otherwise       = textInput

You could do this a bit more compactly by using an anonymous function:

textInput :: IO ()
textInput = getLine >>= dataIn -> if dataIn == "bye" then putStrLn "quitting" else textInput

With a do block, your example could go something like this. This is very similar to the above, only using do with "<-" instead of ">>=" and a function:

textInput :: IO ()
textInput = do
  dataIn <- getLine
  if dataIn == "bye"
    then putStrLn "quitting"
    else textInput

-bob