Q
米蘭達類型錯誤
1
A
回答
2
讓我們嘗試構建類型:
b :: ... ?
我們至少有兩個參數,所以讓我們改變b
相應:
b :: a -> c -> d
的b
右手邊認爲,f
是一個函數。讓我們首先關注的只有第一個參數:
f :: c -> e
到現在爲止,一切都適合相當不錯:列表的第一個參數具有相同的類型B的第二個參數。讓我們繼續在右側。
f x (f x)
如果我們把f x _
,我們必須假設e
是e :: k -> l
,那就是,我們採取另一種說法。我們現在有
f :: c -> k -> l
現在看看f
的第二個參數的類型。它的類型應該是f x
之一:
f x :: k -> l
所以k = k -> l
。這是一個無限的類型,我們也可以通過查看ghci中的錯誤信息,請參閱:
Prelude> let b f x = f x (f x) <interactive>:2:18: Occurs check: cannot construct the infinite type: t1 = t1 -> t0 In the return type of a call of `f' Probable cause: `f' is applied to too few arguments In the second argument of `f', namely `(f x)' In the expression: f x (f x)
類型檢查放棄,因爲無限的類型不能由它來構建。最後,這是因爲您對不同數量的參數應用f
。
1
編譯器試圖推斷出f
的類型。首先它看到f
採用參數x
和另一個參數(f x)
,現在我們將替換爲y
。因此,當編譯器看到類似f x y
的東西時,它推斷f
的類型爲a -> b -> c
,其中x :: a
,y :: b
和f x y :: c
。然後它檢查y
更接近,看到它的類型更具體地b -> c
,因爲它已經知道f
必須有第二個參數。所以現在可以確定b ~ b -> c
。這是它必須停止的地方,b
怎麼樣也是b -> c
?如果它一直代替b ~ b -> c
,它會有一個無限遞歸試圖找出什麼類型b
是!這顯然不能工作,所以它會拋出一個編譯錯誤,說它不能構造無限類型b = b -> c
(注意:錯誤消息可能使用與b
或c
不同的名稱)。該錯誤消息我得到的實際上是相當有幫助的:
Occurs check: cannot construct the infinite type: t1 = t1 -> t0
In the return type of a call of `f'
Probable cause: `f' is applied to too few arguments
In the second argument of `f', namely `(f x)'
In the expression: f x (f x)
這告訴你到底哪裏出了問題「即(f x)
」,併爲您提供可能的原因「f
應用於參數太少」,說它「不能構造無限類型t1 = t1 -> t0
」。
相關問題
- 1. 米蘭達while-和for-loops
- 2. 米蘭達通過列表
- 3. 米蘭達錯誤不能統一[字符]]上線[字符]具有與米蘭達的編碼問題12
- 4. 米蘭達聊天窗口狀態改變信息
- 5. 阿格達類型檢查錯誤
- 6. 類型錯誤綴表達式VHDL
- 7. 阿格達類型的錯誤
- 8. Python正則表達式類型錯誤
- 9. 錯誤:列「ID」的類型UUID的,但表達BYTEA類型
- 10. 類型表達式必須是陣列類型的錯誤JAVA
- 11. 蘭特的C++/OpenMP錯誤
- 12. 可達類錯誤
- 13. 表達式是錯誤的類型--Oracle錯誤
- 14. PL/SQL編譯錯誤 - PLS-00382:表達式類型錯誤
- 15. 錯誤類型的表達式oracle錯誤
- 16. 類型錯誤:錯誤類型與類型化數組
- 17. 類型錯誤
- 18. 錯誤類型
- 19. 類型錯誤
- 20. 類型錯誤
- 21. 類型錯誤:
- 22. 類型錯誤
- 23. 錯誤類型
- 24. 類型錯誤
- 25. JS錯誤類型錯誤
- 26. 錯誤類型錯誤?
- 27. Typescript 1.4聯盟類型,錯誤類型錯誤匹配錯誤
- 28. 亞馬遜阿米 - 錯誤
- 29. Python帕拉米科錯誤
- 30. 的#include(荷蘭國際集團)的文件,用現在的錯誤類型C++
'f'不會「在左邊帶參數」。 'x'不是LHS中'f'的參數。 – user2407038