2017-02-15 90 views
1

就是因爲哈斯克爾函數的返回值

myFilter xs = filter (>100) xs 

myFilter = filter (>100) 
dotEx1 = map(+3) . filter (>100) 

dotEx1 xs = map(+3) . filter (>100) xs 

之間的區別都是一樣的,爲什麼不

dotEx1 = map(+3) . filter (>100) 

dotEx1 xs = map(+3) . filter (>100) xs 

一樣嗎?

+0

由於點運算符? –

+1

我覺得現存的答案實際上並沒有直接解決你的問題:他們說「如何解決它」,而不是「爲什麼它是錯的」。對該部分的單句回答非常簡單:函數應用比任何中綴運算符具有更高的優先級,包括'(。)'。 (但我真的不認爲這一句話增加了足夠的價值以保證提供另一個答案,但是。) –

回答

7

.該函數被定義爲這樣的:

(.) :: (b -> c) -> (a -> b) -> a -> c 

由操作者.組成必須接受一個參數的函數。因此,

dotEx1 = map(+3) . filter (>100) 

相同

dotEx1 xs = (map(+3) . filter (>100)) xs 
4

點運算符具有簽名:

(.) :: (b -> c) -> (a -> b) -> a -> c 

這裏的經營者使用。因此,在您第一次發言,你實際上已經寫:

dotEx1 = (.) (map (+3)) (filter (>100)) 

這是有道理的,因爲filter (>100)有簽名:(Num n,Ord n) => [n] -> [n]map (+3)有簽名Num n => [n] -> [n]。不過,若你寫:

dotEx1 xs = (.) (map (+3)) (filter (>100) xs) 

然後filter (>100) xs有簽名(Num n,Ord n) => [n],因此這是一個值(不是一個功能,或者不帶任何參數的函數)。所以點運算符不能使用(類型不匹配)。

非正式點運算應該給兩個功能fg和和它產生其中fg對輸入施加之後施加的功能。但g因此必須是一個參數的函數。

3

點運算符具有低優先級,因爲您要部分應用函數。也就是說,

map (+3) . filter (>100) 

讀作

(map (+3)) . (filter (>100)) 

通過擴展你

dotEx1 xs = (map (+3)) . (filter (>100) xs) 

,而不是

dotEx1 xs = (map (+3) . filter (>100)) xs 

一個更可讀的版本,也可以工作:

dotEx1 xs = map (+3) . filter (>100) $ xs