为什么编译器会对以下haskell代码给出错误?

时间:2016-03-11 15:13:23

标签: class haskell instance

我正在尝试研究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.

2 个答案:

答案 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