2010-10-23 24 views
2

這是a follow up to a previous question: I got an answer I didn't really understand and accepted。所以,我再問一遍:多態類型的顯式類型簽名。第二部分

我還是不明白這是有道理的:

type Parse a b = [a] -> [(b,[a])] 
build :: Parse a b -> (b -> c) -> Parse a c 
build p f inp = [ (f x, rem) | (x, rem) <- p inp ] 

現在,很明顯,p結合Parse a b類型的第一個參數。而且,顯然f綁定到第二個參數(b -> c)。我的問題仍然是inp綁定到什麼?

如果Parse a b是一種代名詞[a] -> [(b,[a])]我從最後一個問題想我可能只是用它替換:

build :: [a] -> [(b,[a])] -> (b -> c) -> [a] -> [(c,[a])] 

不過,我不認爲這使得任何意義或者與定義:

build p f inp = [ (f x, rem) | (x, rem) <- p inp ] 

有人會幫助解釋類型同義詞。

回答

8

現在,顯然,p綁定到Parse a b類型的第一個參數。而且,再次顯然f綁定到第二個參數(b - > c)。我的問題仍然是什麼inp綁定?

類型的參數[a]

如果解析AB是在[a]型代名詞 - > [(B,[A])我從最後一個問題想我可能只是用它替換:

build :: [a] -> [(b,[a])] -> (b -> c) -> [a] -> [(c,[a])] 

差不多;你需要圓括號換人:

build :: ([a] -> [(b,[a])]) -> (b -> c) -> ([a] -> [(c,[a])]) 

因爲->是右結合的,你可以在最後刪除括號,但在開始時沒有,所以你得到:

build :: ([a] -> [(b,[a])]) -> (b -> c) -> [a] -> [(c,[a])] 

這應該使它顯然爲什麼inp[a]

+0

回答4點環繞聲! – luqui 2010-10-24 03:58:17

4

如果替代

type Parse a b = [a] -> [(b,[a])] 

build :: Parse a b -> (b -> c) -> Parse a c 

build :: ([a] -> [(b,[a])]) -> (b -> c) -> [a] -> [(c,[a])] 

記住x -> y -> z是簡寫x -> (y -> z)這是從(x -> y) -> z很大的不同。第一個函數採用兩個參數x,y並返回z [正好它需要一個參數x並返回一個函數,該函數需要y並返回z];第二種是需要函數x -> y並返回z

3

這裏要記住的重要一點是類型簽名中的箭頭->是正確的關聯。類型a -> (b -> c)a -> b -> c類型相同。

所以類型

Parse a b -> (b -> c) -> Parse a c 

解析

([a] -> [(b,[a])]) -> (b -> c) -> ([a] -> [(c,[a])]) 

通過關聯,您可以刪除最後一個括號,但不是第一個。這就給了你

([a] -> [(b,[a])]) -> (b -> c) -> [a] -> [(c,[a])] 

,它允許你寫build公式與3個參數。

5

你可以替代 - 但不要忘記括號!這應該是:

build :: ([a] -> [(b,[a])]) -> (b -> c) -> ([a] -> [(c,[a])]) 

因爲函數箭頭向右關聯,你可以轉儲右手組括號,但重要的是你不能放棄左邊的新的:

build :: ([a] -> [(b,[a])]) -> (b -> c) -> [a] -> [(c,[a])] 

所以現在,當你有行build p f inp,你可以看到:

p :: ([a] -> [(b,[a])]) 
f :: (b -> c) 
inp :: [a] 

然後我們可以看到:

f inp :: [(b, [a])] 

而且這樣的:

x :: b 
rem :: [a] 

和:

f x :: c 
(f x, rem) :: (c, [a]) 

,因此整個列表具有類型[(c, [a])] - 整齊地匹配什麼build應該返回。希望有所幫助!