[英]“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. 我试图绕过Monads,并感到如果我能解释为什么它不能编译,我会更好地理解。
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. 我意识到问题是我正在尝试将
Maybe
与IO
进行匹配,但是我不确定如何将Maybe'd变量转换为IO。 Any help would be greatly appreciated! 任何帮助将不胜感激!
You are correct in realizing that you are trying to match a Maybe
with an IO
. 您正确地意识到您正在尝试将
Maybe
与IO
进行匹配。 For the bind ( >>=
) operator to typecheck, both the Monad should be the same. 为了使bind(
>>=
)运算符进行类型检查,两个Monad应该相同。 One way to solve this problem would be to wrap the Maybe
in an IO
monad using return
: 解决此问题的一种方法是使用
return
将Maybe
包装在IO
monad中:
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. 话虽如此,您并不需要这里所有花哨的monad运算符。 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. 将
Maybe String
为IO
等同于将Maybe String
为其他任何参数:您需要选择一个值以将Nothing
映射到该值,以及一个值将每个Just x
映射到。 Since you want to map to IO String
, I assume you want to map Nothing
to an exception and Just x
to return x
: 由于您想映射到
IO String
,因此我假设您想将Nothing
映射到一个异常,而Just x
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; 但是,我怀疑在实际的应用程序中,您可能想将
Nothing
映射到已定义的行为上。 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; 基本上,不要太担心
Maybe
和IO
都是单子。 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: 获得
Maybe
值后,仍然需要将它们作为普通的数据结构进行处理(尽管Haskell确实有很棒的方法:
main = maybe (return ()) putStrLn $ myFun "yo"
for example). 例如)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.