Haskell没有...出现的例子

时间:2016-06-08 19:40:37

标签: haskell types numbers typeclass

我试图编写一个测试数字的平方根是否完整的函数。 我的功能如下:

check :: [Int] -> [Int]
check xs = filter (\n -> n == round sqrt n) xs

我收到的错误信息是:

No instance for (Integral (Int -> Int))
(maybe you haven't applied enough arguments to a function?)
arising from a use of "round"
In the second argument of "(==)", namely "round sqrt n"
 ...
No instance for (Floating a0) arising from a use of `sqrt'
The type variable `a0' is ambiguous
Note: there are several potential instances:
instance Floating Double -- Defined in `GHC.Float'
instance Floating Float -- Defined in `GHC.Float'
In the first argument of `round', namely `sqrt'

编辑:我最后改写了整个问题,我希望这不是问题!

3 个答案:

答案 0 :(得分:2)

如果您删除左fromIntegral

,它将起作用
test n = n == fromIntegral (round n) 

原因是,n必须是RealFracround)和IntegralfromIntegral),但没有类型前奏是两者(例如IntegerDouble

如果您删除左侧fromIntegral,则只需要n来获得RealFrac的实例 - Double,例如

右边是这样的:

RealFrac -round-> Integral -fromIntegral-> RealFrac

如果您有疑问,可以随时询问GHCi:

Prelude> :i RealFrac
class (Real a, Fractional a) => RealFrac a where
  properFraction :: Integral b => a -> (b, a)
  truncate :: Integral b => a -> b
  round :: Integral b => a -> b
  ceiling :: Integral b => a -> b
  floor :: Integral b => a -> b
    -- Defined in ‘GHC.Real’
instance RealFrac Float -- Defined in ‘GHC.Float’
instance RealFrac Double -- Defined in ‘GHC.Float’

正如您所看到的,此类型类为您提供了剪切 - 背面数字到Integral的方法(请Integral查看它的内容 - 提示:想想像整数这样的东西)

您还会看到已知的实例

如果您看到RealFrac Int,则表示它正在寻找RealFrac的{​​{1}}实例定义(没有)

为什么有Int是另一回事:

  • 要么你遇到了技术性问题:GHCi默认Intn这里 - 你可能遇到了可怕的monomorphism restriction - 这应该不会发生在更新的GHC版本但是很好。 ..
  • 或者您在将其限制为Int的上下文中使用它(我们没有看到)
说实话,我不确定它在哪里

答案 1 :(得分:2)

应该是

check :: [Int] -> [Int]
check xs = filter (\n -> fromIntegral n == round (sqrt (fromIntegral n))) xs

错误消息告诉您问题:

(maybe you haven't applied enough arguments to a function?)
arising from a use of "round"

由于round sqrt n使用参数roundsqrt调用n

但那仍然没有做你想要的。您还需要sqrt另一方

check :: [Int] -> [Int]
check xs = filter (\n -> sqrt (fromIntegral n) == round (sqrt (fromIntegral n))) xs

答案 2 :(得分:1)

所以我自己找到了另一种解决方案:

check :: [Int] -> [Int]
check xs = filter (\n -> (ceiling (sqrt (fromIntegral n))) == (floor (sqrt (fromIntegral n)))) xs

这是唯一一个不会抛出编译器错误的人(在我的例子中)。