简体   繁体   中英

“Couldn't match type `Maybe' with `IO' Expected type: IO String Actual type: Maybe String” In Haskell

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM