我正在尝试研究haskell中的类型类。我编写以下脚本并引发错误。我无法理解为什么编译器认为v是具体类型,而它只是类Boxer的参数。
data Box1 a b = Box1 Double a [b]
class Boxer v where
foo :: (v a b) -> Double
instance Boxer (Box1 a b) where
foo (Box1 r s t) = r
它在第7行:8中引发错误:
Couldn't match type `v' with `Box1'
`v' is a rigid type variable bound by
the type signature for foo :: v a b -> Double at file1.hs:4:10
Expected type: v a b
Actual type: Box1 a b
Relevant bindings include
foo :: v a b -> Double (bound at file1.hs:7:3)
In the pattern: Box1 r s t
In an equation for `foo': foo (Box1 r s t) = r
Failed, modules loaded: none.
答案 0 :(得分:2)
在您的实例中,编译器必须使用v
实例化Box1 a b
。特别是,它必须用v a b
来实例化(Box1 a b) a b
- 除了a
个变量来自不同的地方;他们实际上消除了(Box1 a b) a1 b1
的歧义。这与Box1 a b a1 b1
相同。
foo :: Box1 a b a1 b1 -> Double
这有意义吗?
问题在于您将(类型)函数(即Box1
)与将结果应用于某种类型的结果混淆参数。 种不匹配:
GHCi> :k Boxer
Boxer :: (* -> * -> *) -> Constraint
GHCi> :k (Box1 Int String)
Box1 Int String :: *
* -> * -> *
是一种带有两个参数的类型函数/类型构造函数,因此Boxer
需要什么。而Box1 a b
只是一种类型,没有参数。不匹配! OTOH,
GHCi> :k Box1
Box1 :: * -> * -> *
答案 1 :(得分:1)
特殊问题是由不正确的缩进引起的。虽然还有另一件事我做错了。所以编译了以下版本:
data Box1 a b = Box1 Double a [b]
class Boxer v where
foo :: (v a b) -> Double
instance Boxer Box1 where
foo (Box1 r s t) = r