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. 米兰达通过列表
- 2. 米兰达while-和for-loops
- 3. 米兰达错误不能统一[字符]]上线[字符]具有与米兰达的编码问题12
- 4. 米兰达聊天窗口状态改变信息
- 5. Python正则表达式类型错误
- 6. 阿格达类型的错误
- 7. 类型错误缀表达式VHDL
- 8. 阿格达类型检查错误
- 9. 类型表达式必须是阵列类型的错误JAVA
- 10. 错误:列“ID”的类型UUID的,但表达BYTEA类型
- 11. 兰特的C++/OpenMP错误
- 12. 可达类错误
- 13. 错误类型的表达式oracle错误
- 14. 表达式是错误的类型--Oracle错误
- 15. PL/SQL编译错误 - PLS-00382:表达式类型错误
- 16. 类型错误:错误类型与类型化数组
- 17. 错误类型
- 18. 类型错误
- 19. 类型错误
- 20. 类型错误:
- 21. 类型错误
- 22. 类型错误
- 23. 错误类型
- 24. 类型错误
- 25. JS错误类型错误
- 26. 错误类型错误?
- 27. Typescript 1.4联盟类型,错误类型错误匹配错误
- 28. Python帕拉米科错误
- 29. 亚马逊阿米 - 错误
- 30. 的#include(荷兰国际集团)的文件,用现在的错误类型C++
'f'不会“在左边带参数”。 'x'不是LHS中'f'的参数。 – user2407038