为什么`fromDouble`不是`Num`的方法?

问题描述 投票:0回答:1

假设我将

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)
类型检查?

haskell
1个回答
0
投票

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
© www.soinside.com 2019 - 2024. All rights reserved.