gpt4 book ai didi

haskell - 为什么 <$> 是左结合的?

转载 作者:行者123 更新时间:2023-12-04 04:02:16 24 4
gpt4 key购买 nike

fmap也是<$>因为它是仿函数类别中的函数应用程序($)。

(+5)  $  (*10)  $  10      -- 105
(+5) <$> (*10) <$> [1,2,3] -- [15,25,35]

然后我想,在那种情况下, <*>是应用仿函数类别中的函数应用程序,这应该有效:
[(+5), (+10)] <*>  [(*10), (*100)] <*> [1,2,3]  -- ERROR
-- however:
[(+5), (+10)] <*> ([(*10), (*100)] <*> [1,2,3]) -- [15,25,35,...]

所以, <$>之所以有效,是因为 fmap因为函数恰好是后合成,所以 (+5) <$> (*10)变成 (+5) . (*10)然后应用于 [1,2,3] .

然而,在我看来,所有应用程序运算符(包括 <<=)的左关联性似乎是一个糟糕的设计选择,尤其是在他们认识到与 $ 的相似性之后。这已经是右结合的。还有其他原因吗?

最佳答案

真的,原因可能只是它允许<$><*>共享一个优先级。我们绝对想要 <*>是左联想的,比如

Prelude> foldr <$> [(+),(*)] <*> [0,1] <*> [[1,2,3], [4,5,6]]
[6,15,7,16,0,0,6,120]

有效,这也使得 <$>即使它没有更高的优先级,也要以正确的方式行事。实际上链接多个 <$>运算符对于左关联性确实不是很有用。

但是,它对于右关联性也不是很有用。正如 chepner 评论的那样, $ 实际上有点有趣。是右结合的。当然,这允许编写像
Prelude> sum $ map (+3) $ take 19 $ cycle [4..7]
160

但是,这也可以写成可以说更优雅
Prelude> sum . map (+3) . take 19 . cycle $ [4..7]
160

(我说得更优雅,因为这里的计算链被解析为单个功能管道,而不是命令式的“做这个,然后那个,然后......”)。由于仿函数定律,这可以用 <$> 相同的方式完成。和 .$ 一样和 . .

您可能更喜欢多个 - $ 的唯一原因风格是它允许管道中的中缀表达式,也许最常见的例子是镜头更新(通常用翻转的 & 编写,但原理是一样的):
Prelude Control.Lens> [4..7] & ix 1+~9 & ix 2*~8
[4,14,48,7]

这是因为 $&具有非常低的优先级,远低于任何中缀运算符。 <$> 的情况并非如此。所以你不能做
Prelude Control.Lens> ix 1+~9 <$> [[4..8], [5..9]]

<interactive>:23:1: error:
Precedence parsing error
cannot mix ‘+~’ [infixr 4] and ‘<$>’ [infixl 4] in the same infix expression

在这种情况下,无论如何您都需要使用一些括号,然后您还不如使用 Control.Category 中的低优先级组合运算符来做到这一点。 :
Prelude Control.Lens Control.Category> (ix 1+~9 >>> ix 2*~8) <$> [[4..8], [5..9]]
[[4,14,48,7,8],[5,15,56,8,9]]

或在每个更新程序周围加上括号:
Prelude Control.Lens> (ix 1+~9) . (ix 2*~8) <$> [[4..8], [5..9]]
[[4,14,48,7,8],[5,15,56,8,9]]

关于haskell - 为什么 <$> 是左结合的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48043167/

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