我试图定义一个类型类Plotable
,它提供一个函数plotable
来返回一个代表图表(x,y)
中坐标的元组,它是{的类型{1}}和x
不必具体(即y
),我认为它们可以是任何数字类型(它们都被移交给Chart)。
我希望Double
能够处理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
,那么在这种情况下,通过相同的值应该有效吗?这仅仅是编译器的限制吗?或者我滥用类型类和类型约束?
答案 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
,因此不够通用。