如何用>>=向Haskell单子函数传递多个值?
用
>>=调用多参数Monadic函数的实现方法 首先明确>>=的核心类型约束:它的类型是(>>=) :: Monad m => m a -> (a -> m b) -> m b——左边必须是一个Monadic值,右边必须是接受单个普通值、返回Monadic值的函数。
你的incVal''和incVal'''是多参数函数,但Haskell中所有多参数函数本质都是柯里化的:比如incVal'' x y等价于(incVal'' x) y,即incVal''接受第一个参数x后,会返回一个接受y并返回m a的函数,这个返回的函数正好符合>>=右操作数的类型要求。基于这个特性,我们可以通过嵌套>>=来调用它们。
调用incVal''的具体实现
场景1:两个值都是Monadic类型
如果要把两个Monadic值(比如Just 3和Just 4)传入incVal'',可以通过嵌套>>=取出每个值,依次传给函数参数:
main = do -- 直接用>>=串联 print $ Just 3 >>= \x -> Just 4 >>= incVal'' x
执行逻辑:
Just 3 >>= \x取出3绑定到x- 剩下的
Just 4 >>= incVal'' x中,incVal'' x是一个a -> m a类型的函数,正好可以和Just 4通过>>=结合,最终返回return (3+4) = Just 7
场景2:一个Monadic值 + 一个普通值
如果第二个参数是普通值(比如5),可以直接在嵌套中传入:
main = do print $ Just 9 >>= \x -> incVal'' x 5
这里incVal'' x 5直接返回return (9+5) = Just 14,本质是跳过了一次>>=(因为第二个参数不需要从Monadic值中取出)。
调用incVal'''的具体实现
incVal'''是三参数函数,同样利用柯里化特性,通过两层嵌套>>=来取出所有Monadic值:
main = do -- 用>>=串联三个Monadic值 print $ Just 2 >>= \x -> Just 3 >>= \y -> Just 4 >>= incVal''' x y
执行逻辑:
Just 2 >>= \x取出2绑定到xJust 3 >>= \y取出3绑定到yincVal''' x y是一个a -> m a类型的函数,和Just 4通过>>=结合,最终返回return (2+3+4) = Just 9
如果其中某个参数是普通值,直接传入即可:
main = do -- 第三个参数用普通值5 print $ Just 2 >>= \x -> Just 3 >>= incVal''' x 5
这段代码会返回return (2+5+3) = Just 10。
等价的do块写法(辅助理解)
Haskell的do语法本质是>>=和>>的语法糖,上面的调用逻辑用do块写会更直观,两者完全等价:
main = do -- 调用incVal''的do块写法 res1 <- do x <- Just 3 y <- Just 4 incVal'' x y print res1 -- 调用incVal'''的do块写法 res2 <- do x <- Just 2 y <- Just 3 z <- Just 4 incVal''' x y z print res2
内容的提问来源于stack exchange,提问作者Ahmad Ismail
相关产品推荐
相关产品推荐

