跨类型类实例使用类型约束

Using type constraints across typeclass instances

我正在尝试定义一个类型 class Plotable,它提供一个函数 plotable 到 return 表示图表中坐标的元组 (x,y), xy 的类型不必具体(即 Double),我认为它们可以是任何数字类型(它们被移交给 Chart).

我希望plotable能够处理Num a => Complex aNum 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,那么在这种情况下应该可以传递相同的值吗?这仅仅是编译器的限制吗?还是我滥用了 typeclasses 和类型约束?

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

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

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

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

id :: a -> a不让用户选择b,不够通用