假设我将
Pair
定义为
data Pair num = Pair num num
和
Pair
像平常一样实现 Num
。
instance (Num num) => Num (Triple num) where
(Pair x1 y1) + (Pair x2 y2) = Pair (x1 + x2) (y1 + y2)
fromInteger i = Pair i i
...
如果
Pair
添加了 int,则此方法有效,例如
10 + (Pair 1.0 42)
但是当添加到
Double
时,类型检查器会变得恼火。
10.0 + (Pair 1.0 42)
No instance for (Fractional (Triple Double))
arising from the literal ‘10.0’
我想
+
只适用于相同的类型(如 a -> a -> a
中所建议的),但当它需要 fromInteger
但得到一个 int 时,它可能会减少并调用 a
。
我的问题是为什么 Double
没有以同样的方式对待(或者可能是 fromIntegral
)?我们如何进行10.0 + (pair 1.0 42)
类型检查?
像
10
这样的整数文字需要目标类型的 Num
实例,而像 10.0
这样的浮点文字则需要 Fractional
实例。
在您的两个表达式中,您都尝试使用这些文字
10
和 10.0
作为 Point Double
类型。对于 Num
的 Point Double
实例,这将适用于 10
。要使其与 10.0
一起使用,您需要一个类似的 Fractional
实例来实现 Point Double
。
以下示例应该有效:
instance (Num num) => Num (Pair num) where
Pair x1 y1 + Pair x2 y2 = Pair (x1 + x2) (y1 + y2)
fromInteger i = let i' = fromInteger i in Pair i' i'
instance (Fractional num) => Fractional (Pair num) where
fromRational i = let i' = fromRational i in Pair i' i'
main = do
print $ 10 + Pair 1.0 42
print $ 10.0 + Pair 1.0 42