有一种方法可以在一个函数中使用多个monad吗?

时间:2019-05-07 07:21:16

标签: haskell monads

我有一个功能

add2Maybe :: (Num a) => Maybe a -> Maybe a -> Maybe a
add2Maybe x y = do
    n1 <- x
    n2 <- y
    return $ n1 + n2

使用Just 8Just 3调用时,它将成功返回Just 5。我想要的是调用此功能时的功能,类似于C中的printf调试,打印

The number in x is 3. --(Or Nothing).
The number in y is 5.
Final result is 8.

并返回Just 8

我得出结论,要定义这样的函数,必须将Maybe monad与IO monad一起使用,但是>>=的类型签名不允许在一个函数中使用两个以上的monad。有没有办法合并Maybe monad和IO monad,更一般地说,有没有办法合并两种或更多monad类型?

2 个答案:

答案 0 :(得分:6)

您正在寻找“单声道变压器”。就像类型IO aMaybe a的值为monad一样,类型IO (Maybe a)的值也可以是monad。此组合使用MaybeT

但是,这是一个高级话题,如果您是概念的新手,那么您会抓狂的。如果只想进行printf样式的调试,请考虑使用Debug.Trace。它使您可以在调试时欺骗类型系统以获取文本输出,但决不能在完成的程序中使用

答案 1 :(得分:2)

如果您只需要add2Maybe实施,则为

add2Maybe :: (Show a, Num a) => Maybe a -> Maybe a -> IO (Maybe a)
add2Maybe x y = do
                 mapM print x
                 mapM print y
                 return $ do 
                  n1 <- x
                  n2 <- y
                  return $ n1 + n2