Haskell:为用户定义的新类型实现 Num instaces



我有一个Pair newtype,它只是一个Double的元组,我希望能够使用这种类型的算术运算符。这是我的代码,它不会编译:

module Test where                                   
newtype Pair = Pair (Double, Double)                
instance Num Pair where                             
  Pair (x1, y1) + Pair (x2, y2) = Pair (x1+x2, y1+y2
  Pair (x1, y1) - Pair (x2, y2) = Pair (x1-x2, y1-y2
  Pair (x1, y1) * Pair (x2, y2) = Pair (x1*x2, y1*y2
  abs (Pair (x, y)) = Pair (abs x, abs y)           
  signum (Pair (x, y)) = Pair (signum x, signum y)  
  fromInteger i = Pair (fromInteger i, fromInteger i)
func :: Pair -> Double -> Pair                      
func p d = p * d                                    

这是 erro GHC 抛出:

[1 of 1] Compiling Test             ( test.hs, interpreted )
test.hs:14:16:
Couldn't match expected type `Pair' with actual type `Double'
In the second argument of `(*)', namely `d'
In the expression: p * d
In an equation for `func': func p d = p * d
Failed, modules loaded: none.

我原以为在这里定义from Integer*就足够了,有人可以建议我做错了什么吗?

更新

如果我添加以下实例:

instance Fractional Pair where                          
  Pair (x1, y1) / Pair (x2, y2) = Pair (x1/x2, y1/y2)   
  fromRational r = Pair (fromRational r, fromRational r)

那么我的函数仍然无法编译,但是在ghci中,我可以做到

> Pair (1.0, 2.0) * 3.4
Pair (3.4,6.8)

但不是:

> Pair (1.0, 2.0) * 3.4 :: Double
<interactive>:206:1:
Couldn't match expected type `Double' with actual type `Pair'
In the return type of a call of `Pair'
In the first argument of `(*)', namely `Pair (1.0, 2.0)'
In the expression: Pair (1.0, 2.0) * 3.4 :: Double

我仍在努力理解为什么会发生这种情况。

func :: Pair -> Double -> Pair
func p d = p * d

您正在尝试将Pair乘以Double,但*的两个参数必须具有相同的类型。

您正在尝试在参数上使用隐式fromInteger,这毫无意义。

首先,fromInteger(或fromRational(只隐含在文字上。即:

6 = fromInteger 6
4.1 = fromRational 4.1

事实并非如此

a = fromInteger a  -- Not true!

您的参数d不是文字,因此您必须手动使用 realToFrac :: (Real a, Fractional b) => a -> b

func :: Pair -> Double -> Pair
func p d = p * realToFrac d

最新更新