help with IO and guards

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

help with IO and guards

Miro Karpis
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..

Cheers,
Miro
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20130601/9cf8099f/attachment.htm>

Reply | Threaded
Open this post in threaded view
|

help with IO and guards

Bob Ippolito
On Fri, May 31, 2013 at 5:02 PM, Miro Karpis <miroslav.karpis at 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20130531/5589b653/attachment.htm>