3
我有以下类型:如何使用类型和为什么编译器抱怨无限类型?
newtype Moi s a =
Moi { runMoi :: s -> (a, s) }
数据构造函数需要一个函数作为参数,它应该返回一个元组。
我尝试以下操作:
*OwnState> :t Moi (+1)
编译器会抱怨:
*OwnState> :t (+1)
(+1) :: Num a => a -> a
类型a
必须是制约:
<interactive>:1:6: error:
* Occurs check: cannot construct the infinite type: s ~ (a, s)
Expected type: s -> (a, s)
Actual type: (a, s) -> (a, s)
* In the first argument of `Moi', namely `(+ 1)'
In the expression: Moi (+ 1)
在(+1)
类型签名首先看Num
typeclass。
所以当我写Moi (+1)
时,会发生什么,类型将如何替代?
让我们来分析错误信息作为下一步:
Occurs check: cannot construct the infinite type: s ~ (a, s)
波浪号意味着~
类型平等和编译器如何来的结论,即s
具有相同的类型(a, s)
?
我想,上面的例子中的类型替代工作在这样:
n -> n "Type of (+1)
| |
s -> (a, s)
然后s
变得(a, s)
和论证s ~ (a, s)
是真实的。
(a, s) -> (a, s)
但我看不出来,为什么它是无限的类型。
因为's'上的左侧和右侧都发生它是无限的'〜'而不是在语义部分。因此,在一次置换后,它是'〜(a,s)〜(a,(a,s))'等。 –
's〜(a,s)'不正确 - 统一失败检查“步骤。事实上,没有类型'T',其中'(a,T)'仍然是相同的类型:第二个直观地包含另外一个'a'。这就像解决数字上的'n = n + 1'一样:除非你以某种方式允许“无限”作为数字,否则它是无法解决的。 – chi
@Willem Van Onsem您可以为我这样的学习者展示如何替换一个类型。我看到很多案例,如何替代作品,但不知道,如果我是对的。 –