liftM函数是否被剥夺了其单调的本质?

问题描述 投票:1回答:1

monad与应用程序之间的区别在于,前者可以根据先前的结果选择下一个计算:

(\x -> if x == 1 then (\_ -> []) else (\y -> (\z -> \w -> [x,y,z]) =<< sqr) =<< (+1)) =<< (+1) $ 0
--                      ^

(\w x -> if x == 1 then (\_ _ -> []) else (\y z -> [x,y,z])) <*> (+1) <*> (+1) <*> sqr $ 0
--                        ^^^

单子计算可以使计算短路,而对于可应用的计算,无论我们提供什么输入,我们都必须使用整个计算结构并运行所有效果。

让我们将其与liftM进行比较:

liftM3 (\x -> if x == 1 then (\_ _ -> []) else (\y z -> [x,y,z])) (+1) (+1) sqr $ 0
--                             ^^^

这似乎是变相的应用风格。即使我将电梯操作员替换为单子涂抹器,整个结构似乎也会失去其单子特性:

appM3 w f x g y h z =
  f(\x' -> g(\y' -> h(\z' -> w x' y' z') z) y) x

appM3 (\x -> if x == 1 then (\_ _ _ -> []) else (\y z _ -> [x, y, z])) (=<<) (+1) (=<<) (+1) (=<<) sqr $ 0
--                            ^^^^^

这是否意味着必须始终手动编码正确的单子计算?我知道符号表示法,但是其基本机制似乎类似于宏扩展(如果这是无稽之谈,请纠正我),因此它并没有真正反驳我的假设。

monad和appalative之间的区别在于,前者可以根据前一个结果选择下一个计算:(\ x->如果x == 1,则(\ _-> [])否则(\ y->(\ z-> \ w-> ...

haskell functional-programming monads applicative lifting
1个回答
4
投票

你是对的。 liftM只是fmap,而liftM2只是liftA2。它们的存在是仍在标准库中化石化的历史文物,而不是实际上需要一元绑定操作的功能的东西。

© www.soinside.com 2019 - 2024. All rights reserved.