2

私はモナドに頭を悩ませようとしていますが、これがコンパイルされない理由を説明できれば、理解が深まると思います。

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

Maybe問題は、 aを と一致させようとしていることにあるとIO思いますが、Maybe'd 変数を IO にキャストする方法が完全にはわかりません。どんな助けでも大歓迎です!

4

2 に答える 2

8

Maybeと を一致させようとしていることに気付いたあなたは正しいですIO。bind( >>=) 演算子が型チェックを行うには、両方の Monad が同じでなければなりません。この問題を解決する 1 つの方法は、 を使用MaybeしてIOモナドでラップすることreturnです。

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

またはもっと簡単に:

return (myFunc "yo") >>= print

そうは言っても、ここで派手なモナド演算子をすべて必要とするわけではありません。これは単純に機能するはずです:

main :: IO ()
main = print . myFunc $ "yo"
于 2014-08-23T00:37:51.023 に答える
3

キャストMaybe StringIOは、a を他のものに変換するのと同じです。マップする値と、それぞれをマップするMaybe String値を選択する必要があります。にマップしたいので、例外とにマップしたいと思います:NothingJust xIO StringNothingJust xreturn 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

Maybe基本的に、とIOが両方ともモナドであるという事実にこだわりすぎないでください。モナド操作は、それらの型の値を作成する方法にすぎません。値を取得したらMaybe、それらを通常のデータ構造として処理する必要があります (ただし、Haskell にはそれを行う優れた方法があります。

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

例えば)。

于 2014-08-23T00:44:56.163 に答える