為什么我不能Data.Function.(&)在與 相同的運算式中使用Control.Arrow.(>>>)?
我在 F# 上花了很多時間之后學習了 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]
顯然沒有。
uj5u.com熱心網友回復:
這不是“優先級錯誤”,而是“優先級決議錯誤”(重點是我的)。
如果我們嘗試在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
因此,如果>>>右側連接的運算式鏈很長,那么括號之間的距離更近,整個運算式可能更具可讀性。
uj5u.com熱心網友回復:
& 具有單獨鏈接的正確優先級:
[1..10] & take 5 & sum
你不需要>>>任何東西在這里,并&和>>>沒有共同設計所以他們的優先級并沒有真正適合這個用例。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/355870.html
