[英]Haskell parentheses for function application binding
我正在學習Haskell。 我定義了以下函數(我知道我不需要addToList
,我也可以做無點符號我只是在玩語言概念):
map :: (a -> b) -> [a] -> [b]
map f [] = []
map f (x:xs) = addToList (f x) map f xs
where
addToList :: a -> [a] -> [a]
addToList x [] = [x]
addToList x xs = x:xs
這會產生編譯錯誤:
with actual type `(a0 -> b0) -> [a0] -> [b0]'
Relevant bindings include
f :: a -> b (bound at PlayGround.hs:12:5)
map :: (a -> b) -> [a] -> [b] (bound at PlayGround.hs:11:1)
Probable cause: `map' is applied to too few arguments
In the second argument of `addToList', namely `map'
In the expression: addToList (f x) map f xs
如果我在地圖周圍放置parantheses它的工作原理:
map :: (a -> b) -> [a] -> [b]
map f [] = []
map f (x:xs) = addToList (f x) (map f xs)
where
addToList :: a -> [a] -> [a]
addToList x [] = [x]
addToList x xs = x:xs
我理解函數應用程序比運算符綁定更緊密(如Haskell中討論的那樣- 參數太少 ),但是,我不明白編譯器如何在沒有parantheses的情況下以不同方式解析上述內容。
看到錯誤的簡單方法是注意表達式:
addToList (f x) map f xs
將4個參數應用於addToList
而:
addToList (f x) (map f xs)
將兩個參數應用於addToList
(這是addToList
“期望的”)。
更新
請注意,即使map
有兩個參數,這個表達式:
addToList a map c d
被解析為:
(((addToList a) map) c) d
所以這里有一個可能的解釋GHC在想什么......
addToList (fx)
具有類型[a] -> [a]
- 即它是一個獲取列表的函數。
map
有類型(c -> d) -> [c] -> [d]
。 它不是一個列表,但有了額外的參數,它可以產生一個列表。
因此,當GHC看到addTolist (fx) map
並且無法鍵入檢查時,它會看到如果map
只有一些參數,如下所示:
addToList (fx) (map ...)
至少addToList
的第二個參數是一個列表 - 所以也許這就是問題所在。
解析是在進行類型檢查之前完成的一個獨特步驟。 表達方式
addToList (f x) map f xs
和s1 (s2 s3) s4 s2 s5
對解析器有同樣的意義。 它對名稱的含義一無所知。 它采用字符串的詞法結構並將其轉換為類似的解析樹
*5
/ \
/ xs
*4
/ \
/ f
*3
/ \
/ map
*2
/ \
addToList *1
/ \
f x
解析樹完成后,每個節點都會標記其類型,並且可以進行類型檢查。 由於函數應用程序僅通過並置表示,因此類型檢查器知道節點的左子節點是函數,右子節點是參數,根節點是結果。
類型檢查器可以大致如下進行,對樹進行預先遍歷遍歷。 (我會略微改變類型簽名,以區分不相關的類型變量,直到它們統一起來。)
addToList :: a -> [a] -> [a]
,所以它采用類型為a
的參數並返回類型為[a] -> [a]
的函數。 值a
尚不清楚。 f :: b -> c
,所以它采用類型為b
的參數並返回類型為c
的值。 b
和c
的值尚不清楚。 x
類型為d
。 d
的值尚不清楚。 b ~ d
, f
可以應用於x
,所以*1 :: c
a ~ c
, addToList
應用於*1
,所以*2 :: [a] -> [a]
*2
期望一個類型為[a]
的參數,但它被應用於map :: (e -> f) -> [e] -> [f]
。 類型檢查器不知道如何統一列表類型和函數類型,這會產生您看到的錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.