Reputation: 363
I'm try to return True or False in this expression, but i'm getting this error, can someone tell me what i'm doing wrong? Thanks.
module Main (main) where
import System.IO (stdout, hSetBuffering, BufferMode(NoBuffering))
main::IO()
simOuNao::String -> Bool
main = do hSetBuffering stdout NoBuffering
putStrLn "Guess Number v1.0"
putStrLn "======================"
simOuNao frase = do putStrLn frase
ans <- readLn
if ans == 'y' || ans =='Y'
then return True
else return False
Error message:
• Couldn't match expected type ‘Bool’ with actual type ‘IO Bool’
• In a stmt of a 'do' block: putStrLn frase
In the expression:
do { putStrLn frase;
ans <- readLn;
if ans == 'y' || ans == 'Y' then return True else return False }
In an equation for ‘simOuNao’:
simOuNao frase
= do { putStrLn frase;
ans <- readLn;
if ans == 'y' || ans == 'Y' then return True else return False }
Failed, modules loaded: none.
Upvotes: 0
Views: 8520
Reputation: 15887
A do
expression is a way to write monadic code in sequence, using lines, let
and <-
. True
and False
are Bool
constructors, and there is no Monad instance for that. There are homomorphic types such as Identity Bool
or Maybe ()
.
Therefore, given the type declaration simOuNao :: String -> Bool
, simOuNao
cannot be defined as a do
expression. Given that you're using putStrLn
inside, it has to return something with the IO
monad. So you've given conflicting goals. return
lifts values into a monadic type. So the simOuNao
version you've written requires specifically the IO
monad, and the type becomes simOuNao :: String -> IO Bool
.
An additional complication is that you've used readLn
. I suspect you meant to use getLine
and checking for strings starting with 'y'
, because as it is the user will need to enter 'y'
complete with quotes as readLn
will expect a character literal.
It is also possible to use monads within a function that has a non-monadic type, including monads like Identity
, Maybe
and State
, typically using some run
function to extract the result. This isn't possible with the IO
monad in particular, because its state is not deterministic (it represents the outside world, so all IO
that is performed must be delegated from main
).
Upvotes: 2
Reputation: 116139
If your function does I/O, you have to declare it in the type by returning IO Bool
instead.
simOuNao :: String -> IO Bool
simOuNao frase = do putStrLn frase
ans <- readLn
if ans == 'y' || ans =='Y'
then return True
else return False
The user of simOuNao
will have to use something like
do ...
b <- simOuNao frase
... -- here b is a Bool
and, of course, the type of this do
expression will have to be IO someType
once again.
Upvotes: 2
Reputation: 152837
Once in IO
, always in IO
-- there is no escape.
simOuNao :: String -> IO Bool
Upvotes: 5