我试图了解类型约束如何与类型别名一起使用。首先,假设我有下一个类型别名:
type NumList a = Num a => [a]
我有下一个功能:
addFirst :: a -> NumList a -> NumList
addFirst x (y:_) = x + y
此函数失败并出现下一个错误:
Type.hs:9:13: error:
• No instance for (Num a) arising from a pattern
Possible fix:
add (Num a) to the context of
the type signature for:
addFirst :: a -> NumList a -> a
• In the pattern: y : _
In an equation for ‘addFirst’: ad
这是显而易见的。这个问题已经在这里描述过:
了解具有类约束的 2 级类型别名 https://stackoverflow.com/questions/14585220/understanding-a-rank-2-type-alias-with-a-class-constraint
我明白为什么我们需要{-# LANGUAGE RankNTypes #-}
此类类型别名是否有效以及为什么前面的示例不起作用。但我不明白的是为什么下一个例子编译得很好(在 ghc 8 上):
prepend :: a -> NumList a -> NumList a
prepend = (:)
当然它失败了ghci
如果我尝试传递错误的值:
λ: prepend 1 []
[1]
λ: prepend "xx" []
<interactive>:3:1: error:
• No instance for (Num [Char]) arising from a use of ‘prepend’
• When instantiating ‘it’, initially inferred to have
this overly-general type:
NumList [Char]
NB: This instantiation can be caused by the monomorphism restriction.
似乎类型类型检查在运行时延迟:(
而且,一些简单的似乎是同一段代码无法编译:
first :: NumList a -> a
first = head
并产生下一个错误:
Type.hs:12:9: error:
• No instance for (Num a)
Possible fix:
add (Num a) to the context of
the type signature for:
first :: NumList a -> a
• In the expression: head
In an equation for ‘first’: first = head
有人可以解释一下这是怎么回事吗?我希望函数类型检查与否具有一定的一致性。