没有(Floating Int)(Fractional Int)的实例

时间:2018-09-26 17:34:14

标签: haskell types haskell-platform

这是我的代码的一部分:

sqa = a*a 
sqb = b*b
endX = (/) (fromIntegral sqa) (sqrt (fromIntegral (sqa + sqb)))

ab均为Int。但是,在其上使用fromIntegral之后,它仍然显示错误No instance for (Floating Int) arising from a use of 'sqrt'No instance for (Fractional Int) arising from a use of '/'。我不知道为什么会这样。谁能帮我吗?

更多上下文:

ellipse :: (Int, Int) -> Int -> Int -> [(Int, Int), Double]
ellipse (xc, yc) a b = plotEllipse1 (xc, yc, xi, yi, di1)
where
   sqa = a*a
   sqb = b*b
   xi = 0
   yi = b
   di1 = 2*sqb - 2*b*sqa + sqa
   endX = (/) (fromIntegral sqa) (sqrt (fromIntegral (sqa + sqb)))
   plotEllipse1 :: (Int, Int, Int, Int, Int) -> Raster
   plotEllipse1 (x0, y0, curX, curY, curD)
     | curX > endX  = plotEllipse2 (xc, yc, curX, curY, di2)
     | otherwise = ...

1 个答案:

答案 0 :(得分:3)

plotEllipse1包含Int s个元组:

plotEllipse1 :: (Int, Int, Int, Int, Int) -> Raster

curX是元组的元素之一,因此它是Int

plotEllipse1 (x0, y0, curX, curY, curD)

您使用curXendX>进行比较:

  | curX > endX  = plotEllipse2 (xc, yc, curX, curY, di2)

>的类型为Ord a => a -> a -> Bool,这意味着左侧和右侧必须为同一类型。

endX的类型属于FractionalFloating类型类,因为您使用sqrt/来获取它。但是请记住,>的左右两侧必须为同一类型,因此curX还必须具有带有这些类型类的类型,但是其类型为Int不是这些类型类的一部分,错误消息在抱怨这些类型类。

那么,我们该如何解决呢?我们将curX转换为endX的类型:

  | fromIntegral curX > endX  = plotEllipse2 (xc, yc, curX, curY, di2)

现在fromIntegral curX应该具有适当的类型。


还请注意,您在其他地方使用过fromIntegral。您只是在需要的地方错过了它。

您可能还需要给endX提供类型签名,以便编译器知道您要使用的 FractionalFloating类型。例如,Double是一个很好的候选人,所以也许您会使用:

endX :: Double
endX = (/) (fromIntegral sqa) (sqrt (fromIntegral (sqa + sqb)))