繁体   English   中英

“无法将类型'Maybe'与'IO'匹配预期类型:IO String实际类型:Maybe String”在Haskell中

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

我试图绕过Monads,并感到如果我能解释为什么它不能编译,我会更好地理解。

module Main where
import Data.Maybe
import System.Environment

myFunc :: String-> Maybe String
myFunc x = Just x

main :: IO ()
main = myFunc "yo" >>= putStrLn 

我得到的错误是

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

我意识到问题是我正在尝试将MaybeIO进行匹配,但是我不确定如何将Maybe'd变量转换为IO。 任何帮助将不胜感激!

您正确地意识到您正在尝试将MaybeIO进行匹配。 为了使bind( >>= )运算符进行类型检查,两个Monad应该相同。 解决此问题的一种方法是使用returnMaybe包装在IO monad中:

return (myFunc "yo") >>= putStrLn . show

或更简单地说:

return (myFunc "yo") >>= print

话虽如此,您并不需要这里所有花哨的monad运算符。 这应该简单地工作:

main :: IO ()
main = print . myFunc $ "yo"

Maybe StringIO等同于将Maybe String为其他任何参数:您需要选择一个值以将Nothing映射到该值,以及一个值将每个Just 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

但是,我怀疑在实际的应用程序中,您可能想将Nothing映射到已定义的行为上。 也许什么也不打印,例如:

main = case myFunc "yo" of
    Nothing -> return ()
    Just x -> putStrLn x

基本上,不要太担心MaybeIO都是单子。 单子操作只是这些类型的值的方法; 获得Maybe值后,仍然需要将它们作为普通的数据结构进行处理(尽管Haskell确实有很棒的方法:

main = maybe (return ()) putStrLn $ myFun "yo"

例如)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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