【发布时间】:2018-06-15 07:26:18
【问题描述】:
我正在尝试定义一个类型类 Plotable,它提供了一个函数 plotable 来返回一个表示图表 (x,y) 中坐标的元组,它的类型 x 和 y 没有必须具体(即Double),我认为它们可以是任何数字类型(它们被移交给Chart)。
我希望plotable 能够处理Num a => Complex a 和Num a => (a, a),所以我写道:
class Plotable a where
plotable :: Num b => a -> (b, b)
instance Num a => Plotable (a, a) where
plotable = id
instance Num a => Plotable (Complex a) where
plotable c = (realPart c, imagPart c)
这对我来说很有意义,但是我收到了错误:
Couldn't match type ‘a’ with ‘b’
‘a’ is a rigid type variable bound by
the instance declaration
at /Users/dan.brooks/Code/haskell/coding-the-matrix/src/TheField/Plot.hs:12:10-33
‘b’ is a rigid type variable bound by
the type signature for:
plotable :: forall b. Num b => (a, a) -> (b, b)
at /Users/dan.brooks/Code/haskell/coding-the-matrix/src/TheField/Plot.hs:13:3-10
Expected type: (a, a) -> (b, b)
Actual type: (b, b) -> (b, b)
但是如果a 被限制为Num,并且b 被限制为Num,那么在这种情况下传递相同的值应该可以工作吗?这仅仅是编译器的限制吗?还是我滥用了类型类和类型约束?
【问题讨论】:
-
社区:也许我们应该有一个参考 q/a 来解决与误解普遍和存在量化相关的问题。最近,这些开始变得越来越普遍。
-
“但是如果 a 被限制为 Num,b 被限制为 Num,那么在这种情况下传递相同的值应该可以工作”——当然不是,否则同样的论点适用于
bad :: a -> b; bad x = x.类型变量在判断上只等于它们自己,这就是为什么编译器说它不能匹配两个不同的类型变量。在某种程度上,这确实是编译器的一个限制——它限制了你编写完全错误的代码。
标签: haskell typeclass type-constraints