I am trying to wrap my head around Monads, and feel that if I could get an explaination to why this doesn't compile, I'd have a better understanding.
module Main where
import Data.Maybe
import System.Environment
myFunc :: String-> Maybe String
myFunc x = Just x
main :: IO ()
main = myFunc "yo" >>= putStrLn
The error I get is
blah.hs:9:10:
Couldn't match type `Maybe' with `IO'
Expected type: IO String
Actual type: Maybe String
In the return type of a call of `myFunc'
In the first argument of `(>>=)', namely `myFunc "yo"'
In the expression: myFunc "yo" >>= putStrLn
I realize that the issue is that I'm trying to match a Maybe
with an IO
, but I'm not entire sure how to cast my Maybe'd variable into an IO. Any help would be greatly appreciated!
You are correct in realizing that you are trying to match a Maybe
with an IO
. For the bind ( >>=
) operator to typecheck, both the Monad should be the same. One way to solve this problem would be to wrap the Maybe
in an IO
monad using return
:
return (myFunc "yo") >>= putStrLn . show
Or more simply:
return (myFunc "yo") >>= print
That being said, you don't need all the fancy monad operators here. This should simply work:
main :: IO ()
main = print . myFunc $ "yo"
Casting Maybe String
to IO
is the same as turning a Maybe String
to anything else: you need to pick a value to map Nothing
to, and a value to map each Just x
to. Since you want to map to IO String
, I assume you want to map Nothing
to an exception and Just x
to return x
:
import Control.Exception
data NoString = NoString deriving (Typeable, Show)
instance Exception NoString
maybeToIO :: Maybe String -> IO String
maybeToIO Nothing = throwIO NoString
maybeToIO (Just x) = return x
main = maybeToIO (myFunc "yo") >>= putStrLn
However, I suspect that, in a real application, you would want to map Nothing
onto defined behavior; maybe printing nothing, for example:
main = case myFunc "yo" of
Nothing -> return ()
Just x -> putStrLn x
Basically, don't get too hung up on the fact that Maybe
and IO
are both monads; the monad operations are just ways of making values of those types; once you've got your Maybe
values, you still need to process them as ordinary data structures (although Haskell does have awesome ways of doing that:
main = maybe (return ()) putStrLn $ myFun "yo"
for example).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.