I have a Pair
newtype which is just a tuple of Double
s and I want to be able to use the arithmetic operators with this type. Here's my code, which doesn't compile:
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
Here's the erro GHC throws:
[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.
I had thought that defining from Integer
and *
would have been enough here, can someone advise what I'm doing wrong?
UPDATE
If I add the following instance:
instance Fractional Pair where
Pair (x1, y1) / Pair (x2, y2) = Pair (x1/x2, y1/y2)
fromRational r = Pair (fromRational r, fromRational r)
then my function still doesn't compile, but in ghci, I can do
> Pair (1.0, 2.0) * 3.4
Pair (3.4,6.8)
but not:
> 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
I'm still struggling to understand why this is happening.
You're trying to use implicit fromInteger
on an argument, which makes zero sense.
Firstly, fromInteger
(or fromRational
) is only implicit on Literals. Ie:
6 = fromInteger 6
4.1 = fromRational 4.1
But this is not true:
a = fromInteger a -- Not true!
Your argument d
is not a literal, so you will have to manually use realToFrac :: (Real a, Fractional b) => a -> b
:
func :: Pair -> Double -> Pair
func p d = p * realToFrac d