haskell - Monad 与 Monad 变压器

标签 haskell monads monad-transformers

“Monads 允许程序员使用顺序构建 block 来构建计算”,因此它允许我们组合一些计算。如果是这样,那为什么下面的代码不能运行呢?

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.."
  • 为什么我们不能将不同的函数放在一个 monad 中(就像上面的例子)?
  • 为什么我们需要一个额外的层,即转换器来组合单子(monad)?
  • 最佳答案

    Monad 转换器是将不同功能放入 monad 的机制。

    monad 只知道如何组合该 monad 能力范围内的计算。您不能在 State 中执行 I/O monad,但你可以在 StateT s IO a单子(monad)。但是,您需要使用 liftIO 关于进行 I/O 的计算。

    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.."
    

    关于haskell - Monad 与 Monad 变压器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45082178/

    相关文章:

    haskell - 如何用递归定义遍历 Monad 并收集结果?

    Haskell Stack 不使用系统 Ghc

    scala - 为什么单子(monad)不在scala中组成

    haskell - 定义一个函数时不使用任何语言扩展,但必须使用语言扩展来声明其类型?

    haskell - 为什么 ListT monad 转换器被认为是错误的 - 它违反了哪些 monad 法则?

    monads - 为什么在编写新的 Monad Transformers 时使用样板

    haskell - 如何将失败的计算转换为成功的计算,反之亦然

    Haskell 与 ContT、callCC 的混淆,当

    Xcode Haskell 语法高亮

    haskell - 处理一个 monad 调用另一个 monad 的干净方法是什么?