如何将二元函数提升至Monad Transformer?
问题原因与解决方案
为什么liftM (+) a b会报错?
liftM本质是fmap的别名,它仅能把一元函数提升到Monad上下文。执行liftM (+) a后,得到的是ExceptT String Maybe (Int -> Int)——这是一个包裹着Int -> Int函数的Monad值,而非能接收ExceptT String Maybe Int类型参数的函数。直接传入b会触发类型不匹配,因为编译器期望的是ExceptT String Maybe Int -> t类型的函数,但实际得到的是Monad包裹的函数。
解决方法
1. 使用liftM2
liftM2专门用于提升二元函数,类型签名为(a -> b -> c) -> m a -> m b -> m c,完全匹配需求:
liftM2 (+) a b
2. 使用Applicative操作符
ExceptT是Applicative类型类的实例,可通过<$>(fmap的中缀形式)和<*>组合实现:
(+) <$> a <*> b
等价写法:
fmap (+) a <*> b
3. 使用do表达式
用更直观的方式提取Monad内的值再运算:
do x <- a y <- b return (x + y)
内容的提问来源于stack exchange,提问作者tolya cow
相关产品推荐
相关产品推荐

