2016-03-11 102 views
0

我想研究haskell中的类型类。我写了下面的脚本,并提出了一个错误。我无法理解为什么编译器将v视为具体类型,而它只是Boxer类的参数。为什么编译器在下面的haskell代码上出错?

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

在这种情况下,错误可能是由于压痕 - 在'foo'声明不与'Boxer'类相关联,因此,预计类型的函数'FORALL V A湾v a b - > Double'。除此之外,'实例Boxer(Box1 a b)'不正确 - 它应该是'实例Boxer Box1'。如果'foo'函数与'Boxer'类正确关联,前者将是一个类型错误。 – user2407038

+0

@ user2407038非常感谢。这确实是由于缩进而导致的错误。 但是,请你解释一下,当我创建一个Foldable的实例时,那里的编译器不让我做实例Foldable Box1。它要求在Box1上放置更多参数。 –

+0

您必须编写'Foldable(Box1 a)'实例'''Foldable'类需要'* - > *'类的参数,而'Box1'类是'* - > * - > *'。 – user2407038

回答

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 
2

在您的实例,编译器实例vBox1 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 :: * -> * -> * 
+0

这解决了代码中的语义错误,但OP中的类型错误是由于原始代码中的不正确缩进引起的。 – user2407038

相关问题