2017-07-13 1 views
4

"モナドは、プログラマが順次ビルディングブロックを使用して計算を構築することを可能にする"ので、いくつかの計算を組み合わせることができます。この場合、次のコードを実行できない理由は何ですか?モナド対モナド変圧器

import Control.Monad.Trans.State 

gt :: State String String 
gt = do 
    name <- get 
    putStrLn "HI" -- Here is the source of problem! 
    put "T" 
    return ("hh..." ++ name ++ "...!") 


main= do 
    print $ execState gt "W.." 
    print $ evalState gt "W.." 
  • なぜ我々は(上の例のように)モナドで異なる機能を置くことができませんか?

  • なぜモナドを組み合わせるために追加のレイヤー、つまりトランスが必要なのですか?モナドで異なる機能を置くため機構である

答えて

8

モナド変圧器。

モナドは、そのモナドの能力内にある計算をどのように組み合わせるかを知っています。 StateモナドでI/Oを実行することはできませんが、StateT s IO aモナドで行うことはできます。ただし、I/Oを行う計算ではliftIOを使用する必要があります。

import Control.Monad.Trans.State 
import Control.Monad.IO.Class (liftIO) 

gt :: StateT String IO String 
gt = do 
    name <- get 
    liftIO $ putStrLn "HI" 
    put "T" 
    return ("hh..." ++ name ++ "...!") 


main = do 
    print =<< execStateT gt "W.." 
    print =<< evalStateT gt "W.." 
+0

ありがとうございます!最後の2行で= =を使った理由を教えてください。 – 4xx

+4

['execStateT'](http://hackage.haskell.org/package/transformers-0.5.4.0/docs/Control-Monad-Trans-State-Lazy.html#v:execStateT)と[' evalStateT']( http://hackage.haskell.org/package/transformers-0.5.4.0/docs/Control-Monad-Trans-State-Lazy.html#v:evalStateT)は両方ともここで 'IO String'を返します。それらの中に 'String'を表示します。 ['= <<'](http://hackage.haskell.org/package/base-4.9.1.0/docs/Prelude.html#v:-61--60--60-)は、左の関数を呼び出します右側のモナドの内側の値を使用します。 – 4castle

+0

@ 4xxこの同等のバージョンは、もっとおなじみかもしれません: 'main = do x < - execStateT gt" W .. "; xを印刷する。 y < - evalStateT gt "W .."; print y' – chi

関連する問題