Haskell 为什么<$&燃气轮机;左联想?

Haskell 为什么<$&燃气轮机;左联想?,haskell,apply,associativity,design-rationale,design-choices,Haskell,Apply,Associativity,Design Rationale,Design Choices,fmap也是,因为它是functor类别中的函数应用程序($) (+5) $ (*10) $ 10 -- 105 (+5) <$> (*10) <$> [1,2,3] -- [15,25,35] (+5)$(*10)$10--105 (+5) (*10) [1,2,3] -- [15,25,35] 然后我想,在这种情况下,是applicative functor类别中的函数应用程序,应该可以: [(+5), (+10)] <*> [

fmap
也是
,因为它是functor类别中的函数应用程序(
$

(+5)  $  (*10)  $  10      -- 105
(+5) <$> (*10) <$> [1,2,3] -- [15,25,35]
(+5)$(*10)$10--105
(+5)  (*10)  [1,2,3] -- [15,25,35]
然后我想,在这种情况下,
是applicative functor类别中的函数应用程序,应该可以:

[(+5), (+10)] <*>  [(*10), (*100)] <*> [1,2,3]  -- ERROR
-- however:
[(+5), (+10)] <*> ([(*10), (*100)] <*> [1,2,3]) -- [15,25,35,...]
[(+5),(+10)][(*10),(*100)][1,2,3]--错误
--然而:
[(+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]
但是,这本书也可以写得更优雅

Prelude> sum . map (+3) . take 19 . cycle $ [4..7]
160
(我说得更优雅,因为这里的计算链被解析为一个单一的函数管道,而不是命令式的“做这个,然后那个,然后…”)。由于函子定律,这可以用与
相同的方法来完成

您可能更喜欢multiple-
$
样式的唯一原因是它允许在管道中使用中缀表达式,可能最常见的示例是镜头更新(通常使用翻转的
&
编写,但原理相同):

这是因为
$
&
的优先级非常低,几乎比任何中缀运算符都低。这不是
的情况,所以您不能这样做

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
或者在每个更新程序周围使用parens:

Prelude Control.Lens> (ix 1+~9) . (ix 2*~8) <$> [[4..8], [5..9]]
[[4,14,48,7,8],[5,15,56,8,9]]
前奏曲控制镜头>(ix 1+~9)。(ix 2*~8)[[4..8],[5..9]]
[[4,14,48,7,8],[5,15,56,8,9]]

函数应用程序本质上是左关联的;一个更好的问题是为什么
$
是右关联的?另外,
fmap
更好地被认为是函数提升而不是函数应用程序。一旦
fmap
返回提升的函数,它将与任何其他函数一样被应用;没有特殊的应用程序重新启动要求。
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
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]]