在类型类实例中使用类型约束

时间:2018-01-05 13:11:20

标签: haskell typeclass type-constraints

我试图定义一个类型类Plotable,它提供一个函数plotable来返回一个代表图表(x,y)中坐标的元组,它是{的类型{1}}和x不必具体(即y),我认为它们可以是任何数字类型(它们都被移交给Chart)。

我希望Double能够处理plotableNum 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,那么在这种情况下,通过相同的值应该有效吗?这仅仅是编译器的限制吗?或者我滥用类型类和类型约束?

1 个答案:

答案 0 :(得分:1)

plotable :: Num b => a -> (b, b)

表示其中任何一个都必须输入

plotable :: a -> (Int, Int)
plotable :: a -> (Integer, Integer)
plotable :: a -> (Double, Double)
...

换句话说,该多态类型向用户承诺plotable可以使用用户可以选择的任何数字类型b

id :: a -> a不允许用户选择b,因此不够通用。