haskell - 一起使用 Maybe 和 Writer

标签 haskell monads monad-transformers

这是我的鸡蛋包装厂:

type Eggs = Int
data Carton = Carton Eggs deriving Show

add :: Eggs -> Carton -> Maybe Carton
add e (Carton c)
    | c + e <= 12 = Just (Carton $ c + e)
    | otherwise = Nothing

main = do
    print $ pure(Carton 2) >>= add 4 >>= add 4 >>= add 3

似乎运作良好,我可以很好地链接 add职能。

但是我想记录每一步添加了多少鸡蛋的日志。所以我这样做:
import Control.Monad.Writer

type Eggs = Int
data Carton = Carton Eggs deriving Show

add :: Eggs -> Carton -> Writer [String] (Maybe Carton)
add e (Carton c)
    | c + e <= 12 = do
        tell ["adding " ++ show e]
        return (Just (Carton $ c + e))
    | otherwise = do
        tell ["cannot add " ++ show e]
        return Nothing

main = do
    let c = add 4 $ Carton 2
    print $ fst $ runWriter c
    mapM_ putStrLn $ snd $ runWriter c

这给了我想要的东西:我可以看到生成的纸箱和添加 4 个鸡蛋的记录。

但是我好像失去了上链的能力add像我以前一样的功能:
let c = pure(Carton 2) >>= add 4 -- works
let c = pure(Carton 2) >>= add 4 >>= add 2 -- does not work

如何链接我的新启用作家的 add职能?有没有更好的方法来做到这一点?

最佳答案

只需撰写 addMaybeT :

import Control.Trans.Monad.Maybe

test = pure (Carton 2) >>= MaybeT . add 3
                       >>= MaybeT . add 4
                       >>= MaybeT . add 5

runTest = do
  print $ fst $ runWriter (runMaybeT test)

完整示例位于:http://lpaste.net/169070

关于haskell - 一起使用 Maybe 和 Writer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38194378/

相关文章:

haskell - ReaderT Monad Transformer 中 * 的用途是什么?

list - Haskell处理Maybe列表

list - 我的递归列表构造有什么问题?

haskell - Haskell 中的 Floating 和 Fractional 类有什么区别?

haskell - 如何正确地将 IO 添加到 attoparsec Parser?

haskell - 也许在一个单子(monad)中

haskell - 具有不同类型中断的状态循环

sql - filterLogging 不适用于 Database.Persist.Sql 的 runSqlPool 函数

仿函数的 Haskell 类型推断

haskell - 如何将 stdout/stderr 通过管道传输到 Turtle 中另一个命令的 stdin?