我對Haskell來說很新,所以我希望這不是一個愚蠢的問題。我有這樣的數據類型:應用函數的參數可能是Ints或雙精度
data N = I Int | D Double deriving (Show, Eq)
我想寫與該功能適用於數字的N
秒鐘內,並返回結果的N簽名(Num a) => (a -> a -> a) -> N -> N -> N
的功能。如果N
s都是D
s,則應該只應用該函數並返回D
;如果一個人是一個I
,另一個是D
,它應該在I
的Int
轉換爲Double
,應用功能兩個Double
S,並返回一個D
;如果兩者都是I
s,則應該應用該功能並返回I
。這裏的(壞)的代碼,我到目前爲止有:
widen :: N -> N -> (N, N)
widen (I i) [email protected](D _) = (D (fromIntegral i), d)
widen [email protected](D _) [email protected](I _) = widen i d
widen x y = (x, y)
numOp :: (Num a) => (a -> a -> a) -> N -> N -> N
numOp op x y = case widen x y of (D x', D y') -> D $ x' `op` y'
(I x', I y') -> I $ x' `op` y'
我得到的numOp
兩行的錯誤,雖然。第一個是:
Could not deduce (a ~ Double)
from the context (Num a)
bound by the type signature for
numOp :: Num a => (a -> a -> a) -> N -> N -> N
at <line num>
In the second argument of `($)', namely x' `op` y'
In the expression: D $ x' `op` y'
In a case alternative: (D x', D y') -> D $ x' `op` y'
而第二個:
Couldn't match type `Double' with `Int'
Expected type: Int
Actual type: a
In the second argument of `($), namely x' `op` y'
In the expression: I $ x' `op` y'
In a case alternative: (I x', I y') -> I $ x' `op` y'
我敢肯定,我明白這兩個錯誤的意思;我認爲第一個意思是說,我的類型簽名中的信息不足以讓GHC假定op
返回D
值構造函數所要求的Double
,第二個說法是因爲第一行意味着a
是Double
,此行不能使用類型a
的值,就好像它是Int
。不過,我不知道從哪裏開始尋找正確的方法來做到這一點。
如果有幫助,我試圖得到這個工作的原因是,我跟着Write Yourself a Scheme tutorial;本教程中的所有示例(特別是在Evaluation section中)只涉及整數,但作爲練習,我希望增加支持整數和浮點數的功能,例如, (+ 1 2.5 2.5)
返回6.0
和(+ 1 2 3)
返回6
。如果我想到這是錯誤的方式,或者有更簡單的方法來實現它,我很樂意聽到建議。
不是一個愚蠢的問題。這個問題是一個相當不明顯的問題。 –