我有一个Pair
新类型,它只是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
我仍然在努力理解为什么会这样。
答案 0 :(得分:3)
func :: Pair -> Double -> Pair
func p d = p * d
您尝试将Pair
乘以Double
,但*
的两个参数必须具有相同的类型。
答案 1 :(得分:2)
你试图在一个参数上使用隐式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