为什么我不能在与 Control.Arrow.(>>>) 相同的表达式中使用 Data.Function.(&)?

Why can't I use Data.Function.(&) in the same expression as Control.Arrow.(>>>)?

为什么我不能在与 Control.Arrow.(>>>) 相同的表达式中使用 Data.Function.(&)

我在 F# 中花费了大量时间后正在学习 Haskell,我发现从右到左的符号很难理解更长的管道。 (我知道这不是惯用语)

我读到 &>>> 是 Haskell 等同于 F# 的 |>>>。然而,这失败了:

[someList] & take 5 >>> sum

出现“优先顺序错误”:

Prelude Data.Function Control.Arrow> [1:10] & take 5 >>> sum
<interactive>:4:1: error:
    Precedence parsing error
        cannot mix `&' [infixl 1] and `>>>' [infixr 1] in the same infix expression

sum . take 5 $ [someList]

显然不是。

& 有正确的优先级可以单独链接:

[1..10] & take 5 & sum

此处的任何内容都不需要 >>>,并且 &>>> 不是共同设计的,因此它们的优先级并不适合此用例。

这不是“优先级错误”,而是“优先级 解析 错误”(强调我的)。

如果我们在 GHCi 中尝试,> :i & 回复 infixl 1 &,而 > :i >>> 回复 infixr 1 >>>

所以一个(&)括号在左边(infixl),另一个(>>>)在右边(infixr)。

优先级高的获胜,但这两个具有相同的优先级(1)。这就是错误消息告诉我们的(有点不恰当):

    Precedence parsing error
        cannot mix `&' [infixl 1] and `>>>' [infixr 1] in the same infix expression

意味着,因为它们具有相同的优先级,所以这些左关联和右关联中缀运算符的解析在此混合在一起表达式不明确,因此不可能。

所以你最终不得不为这个表达式使用显式括号才能正确解析:

[someValue] & (take 5 >>> sum)

顺便说一下,[someValue] 已经是一个列表。因为你使用 sum 它的一个元素的类型必须在 Num (someValue :: Num a => a, [someValue] :: Num a => [a]).

但是如果你已经有了 someList 其中有几个数值 (someList :: Num a => [a]),你只需写

someList & (take 5 >>> sum)

因为[someList]是一个列表,其中只有一个值,恰好是一个数字列表(大概)。所以使用 [someList] 表达式无论如何都不起作用:

> [5] & (take 5 >>> sum)
5

> [[3,4,5]] & (take 5 >>> sum)

<interactive>:431:1:
    No instance for (Num [t0]) arising from a use of `it'
    In a stmt of an interactive GHCi command: print it

另一种让它解析的方法是

(someList &) $ take 5 >>> sum

所以括号靠得更近,整个表达式可能更具可读性,如果你有一长串表达式与右边的 >>> 相连。