我有一個函數g1 = flip map . (flip take $ iterate (+1) 1)
我很奇怪,爲什麼我不能寫操作的優先級在Haskell
g1 = flip map . $ flip take $ iterate (+1) 1
? 我知道$
優先級最低,但不明白爲什麼我們可以點後有flip take $ iterate (+1) 1
$
但不是在g1
我有一個函數g1 = flip map . (flip take $ iterate (+1) 1)
我很奇怪,爲什麼我不能寫操作的優先級在Haskell
g1 = flip map . $ flip take $ iterate (+1) 1
? 我知道$
優先級最低,但不明白爲什麼我們可以點後有flip take $ iterate (+1) 1
$
但不是在g1
注意,第二種形式導致解析錯誤,而不是一個類型的錯誤。你根本不能有兩個操作員並排。當你在.
和$
,之間加上一個表達式時,運營商的優先級就會發揮作用。由於.
具有更高的優先級,因此.
和$
之間的表達式成爲.
的右操作數,並且點運算符的結果成爲美元的左操作數。如果你想扭轉他們的優先級(或者假設他們已經寫了代碼),你會得到一個類型錯誤(除非類型恰好匹配)。
可以使用操作部分寫類似第二種形式:
g1 = (flip map .) $ flip take $ iterate (+1) 1
但我要說最可讀的自由點符號是
g1 = flip map . flip take (iterate (+1) 1)
而實際上iterate (+1) 1
可縮短:
g1 = flip map . flip take [1..]
接下來,有點desugaring幫助我們擺脫了flip take
:
g1 = flip map . enumFromTo 1
讓我們一個更簡單的例子:
Prelude> :t id . (id)
id . (id) :: c -> c
Prelude> :t id . $ id
<interactive>:1:6: parse error on input `$'
Prelude> :t (id .) $ id
(id .) $ id :: c -> c
的$
運營商已經非常低優先級,因此它最後一次評估,並採取了功能作爲左邊參數:
Prelude> :i ($)
($) :: (a -> b) -> a -> b -- Defined in `GHC.Base'
infixr 0 $
不幸的是,沒有括號,這些情況下你沒有得到適當的功能:
Prelude> :t id .
<interactive>:1:5:
parse error (possibly incorrect indentation or mismatched brackets)
Prelude> :t (id .)
(id .) :: (a -> c) -> a -> c
Prelude> :t flip take
flip take :: [a] -> Int -> [a]
Prelude> :t flip map .
<interactive>:1:11:
parse error (possibly incorrect indentation or mismatched brackets)
Prelude>
這是一樣的道理,爲什麼你指的是加運算本身時需要寫(+)
:
Prelude> :t +
<interactive>:1:1: parse error on input `+'
Prelude> :t (+)
(+) :: Num a => a -> a -> a
Prelude> :t 1+
<interactive>:1:3:
parse error (possibly incorrect indentation or mismatched brackets)
Prelude> :t (1+)
(1+) :: Num a => a -> a
結論:你根本不能有兩個運營商通過側直接側。