gpt4 book ai didi

haskell - monad bind (>>=) 运算符是否更接近函数组合(链接)或函数应用程序?

转载 作者:行者123 更新时间:2023-12-03 13:26:54 25 4
gpt4 key购买 nike

在许多文章中,我读过那个 monad >>=运算符是一种表示函数组合的方式。但对我来说它更接近某种高级功能应用

($)   :: (a -> b) -> a -> b
(>>=) :: Monad m => m a -> (a -> m b) -> m b

对于组合,我们有
(.)   :: (b -> c) -> (a -> b) -> a -> c
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c

请说清楚。

最佳答案

显然,>>=不是一种表示功能组合的方式。函数组合只需使用 . .但是,我认为您读过的任何文章也不是这个意思。

他们的意思是“升级”函数组合以直接使用“一元函数”,即 a -> m b 形式的函数.此类函数的技术术语是 Kleisli 箭头,实际上它们可以由 <=< 组成。或 >=> . (或者,您可以使用 Category instance ,然后您也可以使用 .>>> 组合它们。)

然而,谈论箭头/类别往往会让初学者感到困惑,就像 point-free definitions的普通函数往往令人困惑。幸运的是,Haskell 还允许我们以更熟悉的风格表达函数,这种风格专注于函数的结果,而不是将函数本身作为抽象态射†。它是通过 lambda 抽象完成的:而不是

q = h . g . f

你可以写
q = (\x -> (\y -> (\z -> h z) (g y)) (f x))

...当然首选的风格是(这只是 lambda 抽象的语法糖!)‡
q x = let y = f x
z = g y
in h z

请注意,在 lambda 表达式中,组合基本上是如何被应用程序替换的:
q = \x -> (\y -> (\z -> h z) $ g y) $ f x

适应 Kleisli 箭头,这意味着代替
q = h <=< g <=< f

你写
q = \x -> (\y -> (\z -> h z) =<< g y) =<< f x

使用翻转运算符或语法糖看起来当然更好:
q x = do y <- f x
z <- g y
h z

所以,确实, =<<<=<喜欢 $. .将其称为组合运算符仍然有意义的原因是,除了“应用于值”之外, >>=运算符还对 Kleisli 箭头组合做了一些重要的事情,而函数组合不需要:加入单子(monad)层。

†这个工作的原因是 哈斯克cartesian closed category ,特别是 well-pointed category .从广义上讲,在这样的类别中,箭头可以通过将其应用于简单参数值时的所有结果的集合来定义。

‡@adamse 指出 let不是 lambda 抽象的真正语法糖。这在递归定义的情况下尤其重要,您不能直接使用 lambda 编写。但在这种简单的情况下, let确实表现得像 lambdas 的语法糖,就像 do符号是 lambda 和 >>= 的语法糖. (顺便说一句,有一个扩展允许递归 even in do notation ...它通过使用定点组合器来规避 lambda 限制。)

关于haskell - monad bind (>>=) 运算符是否更接近函数组合(链接)或函数应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34545818/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com