2016-03-02 49 views
1

當看到有關修復,因爲我很感興趣,在我的代碼有遞歸lambda表達式我來到代碼這個特殊的例子(從Here):Haskell的類型和修復遞歸的例子

fix (\rec n -> if n == 0 then 1 else n * rec (n-1)) 5 

現在忽略的類型簽名修復我覺得這段代碼錯了:

修復類型是(a -> a) -> a,而lambda的類型是(a -> a) -> a -> a我確定我正在閱讀這段代碼錯誤,但我第一次閱讀它的方式是「修復應用於兩個參數」這是錯誤的,因爲修復只接受一個參數,一個函數(a - > a),肯定會有一些我明顯缺失的東西。

然後我看了一下lambda的類型和修復類型,它對我來說似乎「堅持,是不是有很大的不匹配?我可以理解,使用curried函數可以提供類型的函數a -> a -> a沒有足夠的論據來創建一個新的功能,但在這裏我喂(a -> a) -> a -> a(a -> a) -> a功能,好像我試圖通過針孔傳遞大象,喂錯參數修復功能。

我的內部語法分析器和類型檢查器(腦1.0)在評估這條線時出了什麼問題?

+1

我想你是假設因爲這兩種類型的類型變量被稱爲'a',它必須是相同的類型。事實並非如此 - 當你有一個函數'fix ::(a - > a) - > a''你真正擁有的就是'a a。 (a→a)→a'。這裏'a'可以被實例化爲任何類型。在這種情況下,你有'a〜(x - > x)'所以'fix ::((x - > x) - >(x - > x)) - > x - > x'有兩個參數。 – user2407038

回答

1

您可以讀取lambda的類型爲:

(b -> b) -> (b -> b) 

這可能會使它更清晰當你將它提供給fix時發生了什麼。返回的值是另一個函數b -> b,然後在您的示例中立即應用參數5