data Tick = Tick
{ _price :: Int
, _timestamp :: TimeOfDay
} deriving (Eq, Ord)
instance Num Tick where
(-) (Tick a b) (Tick a' _) = Tick (a - a') b
calcAxis :: High -> Low -> Int
calcAxis (Just (Tick a _)) (Just (Tick b _)) = (fromIntegral (a - b)) / 2
我知道将Int
分开会产生Float
,因此我需要在使用Int
之前使用fromIntegral
转换(/)
{1}}但是我仍然会收到错误:
• No instance for (Fractional Int) arising from a use of ‘/’
• In the expression: (fromIntegral (a - b)) / 2
In an equation for ‘calcAxis’:
calcAxis (Just (Tick a _)) (Just (Tick b _))
= (fromIntegral (a - b)) / 2
我真的不明白它要求我做什么。当然,我不必为Fractional Int
定义一个实例?
我认为我做错了什么。
答案 0 :(得分:3)
问题是你在使用/
之后最终得到一个浮点数,你的类型规范说你应该返回一个Int。
您需要舍入/截断转换为Int或更改calcAxis的类型签名。
> let a = 1 :: Int
> let b = 2 :: Int
> let c = (fromIntegral (a - b)) / 2
> :t c
c :: Fractional a => a
并且Fractional Int
没有实例是类型错误指示的内容。
答案 1 :(得分:3)
正如Ryan评论的那样,将结果保持为小数类型可能是正确的。 {HESell}中Float
非常不寻常,通常会选择更高精度Double
或精确Rational
。
calcAxis :: High -> Low -> Double
calcAxis (Just (Tick a _)) (Just (Tick b _)) = fromIntegral (a - b) / 2
calcAxis _ _ = ... -- keep in mind to handle the `Nothing` case as well!
那就是说,如果你有理由做出结果Int
,并且总是希望向零舍入,那么只需使用整数除法即可:
calcAxis :: High -> Low -> Int
calcAxis (Just (Tick a _)) (Just (Tick b _)) = (a - b) `quot` 2
......或者,如果你总想要四舍五入,
calcAxis (Just (Tick a _)) (Just (Tick b _)) = (a - b) `div` 2