2013-07-22 53 views
4

我的問題是關於如何使用Haskell類型簽名進行分析。爲了使具體的,我在看「修復」功能:簡化Haskell類型簽名

fix :: (a -> a) -> a 

和我寫做皮亞諾十歲上下又多了一點虛構的功能:

add = \rec a b -> if a == 0 then b else rec (a-1) (b+1) 

當我檢查類型,我得到我預期的類型fix add

fix add :: Integer -> Integer -> Integer 

而且它似乎工作像我期望:

> (fix add) 1 1 
2 

如何使用fixadd的類型簽名來顯示fix add具有上述簽名?什麼是「代數」,如果這甚至是合適的詞,使用類型簽名的規則?我怎樣才能「展示我的作品」?

回答

8

ghci告訴我們

add :: Num a => (a -> a -> a) -> a -> a -> a

模某些類型類的噪音,因爲第二個參數add需要一個Eq實例(你檢查它與0平等)

在申請fixaddfix的簽名變爲

fix :: ((a -> a -> a) -> (a -> a -> a)) -> (a -> a -> a)

記住,a S IN fix :: (a -> a) -> a可以有任何類型。在這種情況下,他們有型(a -> a -> a)

因此fix add :: Num a => a -> a -> a,而這正是添加兩個a正處於成長的類型。

你可以用非常代數的方式使用Haskell的類型簽名,變量替換就像你期望的那樣工作。事實上,類型和代數之間的直接關係爲translation

+0

謝謝!我已經制定了很多(即'fix'中的'a'必須是'(a - > a - > a)')。但是,還沒有一個步驟仍然存在?在((a - > a - > a) - >(a - > a - > a)) - >(a - > a - > a)和a - > a - > a' ? – Chris

+0

是的,你部分地將'fix'應用於'add'。由此產生的部分應用函數的類型爲'a - > a - > a' – cdk

+3

@ twopoint718將'fix'應用於'add'會刪除'((a→a→a)→a→a→a ))來自'fix'類型的參數。 –