【问题标题】:No instance for (Fractional Int) arising from a use of ‘/’没有因使用“/”而产生 (Fractional Int) 的实例
【发布时间】:2018-03-09 09:28:36
【问题描述】:
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,所以我需要在使用fromIntegral 之前使用Int 转换(/) 但是我仍然得到错误:

• 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 定义一个实例?

我认为我做错了什么。

【问题讨论】:

  • 如果我理解正确,错误消息是在抱怨整个表达式 (fromIntegral (a - b)) / 2 — 这是 Fractional,但您已经询问(通过 calcAxis 的类型签名)它是 @ 987654331@.
  • 如果我删除除法并更新calcAxis 的签名以返回Float,则类型检查正常。
  • @Globalkeith:你为什么要两者都做?更新签名以返回 Float 并且不要删除除法。
  • Doh,忽略我 - 它会在返回 Float 时进行类型检查!谢谢
  • 是的,将结果保留为小数类型可能是正确的。虽然 Float 在 Haskell 中很不寻常,但通常更高精度的 Double 或精确的 Rational 是首选。

标签: haskell


【解决方案1】:

正如 Ryan 评论的那样,将结果保留为小数类型可能是正确的做法。 Float 在 Haskell 中很不寻常,通常更高精度的 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

【讨论】:

  • 谢谢你,对于我这个级别的任何人,这个回复都具有丰富的教育价值。我很感激。
  • 我希望我不会因为选择此回复而冒犯任何人,但它超越了对我的帮助,因此值得认可,并且对未来的用户有所帮助。
【解决方案2】:

问题是你在使用 / 后得到一个浮点数,而你的类型规范说你应该返回一个 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 的实例是类型错误所指示的。

【讨论】:

  • 感谢您的详细回答,非常感谢。是的,当@Shreevatsar 询问签名时,我意识到了。
猜你喜欢
  • 1970-01-01
  • 2015-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多