Haskell中的实例声明 [英] Instance declaration in Haskell

查看:281
本文介绍了Haskell中的实例声明的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这两个函数:

  primes = sieve [2 ..] 
其中
筛(p:xs)= p:筛[x | x < - xs,x`mod'p> 0]
isPrime number = number / = 1&& null [x | x< - takeWhile(\ x - > x<(ceiling。sqrt)number)primes,mod number x == 0]

问题是,当我试图加载包含这些函数的模块时,我看到以下错误消息:

  [2 of 2]编译Main(euler37.hs,解释)

euler37.hs:6:70:
(RealFrac Int)$ b没有实例$ b使用`ceiling'
可能的修正:为(RealFrac Int)添加一个实例声明
在`(。)'的第一个参数中,即`ceiling'
In表达:天花板。 sqrt
在'(<)'的第二个参数中,即'(ceiling。sqrt)number'

euler37.hs:6:80:
没有Floating Int)使用`sqrt'引起的

可能的修正:为(Floating Int)添加一个实例声明
在'(。)'的第二个参数中,即`sqrt'
在表达式中:天花板。 sqrt
在'(<)'的第二个参数中,即'(ceiling。sqrt)数字'

我真的不明白是什么问题,因为当我试图从一段代码中创建一个小函数时,据我所知,这些代码会导致这些错误,就像gb中的$ b一样$ b let f number x = x < (ceiling。sqrt)number
我看不到任何错误消息。

解决方案

问题在于 primes 是整数列表(由于您使用 mod ),但 sqrt 操作浮点数。如果你做 x < (天花板上的sqrt.quatrt)数字,那么它会正常工作。 fromIntegral 只是将整数转换为任何其他数字类型:

  fromIntegral ::(积分a,数字b)=> a  - > b 

在这种情况下,由于您没有指定任何特定的浮点类型来转换,它将默认使用Double值来计算平方根。您可以通过将 fromIntegral 更改为类似于(fromIntegral :: Integer - > Float)的方式指定其他类型。 p>

你在GHCi中看不到这个错误的原因是因为你的条件很好;它只适用于你在这里使用的不同类型。只是验证一段代码是孤立的,是不够的;因为它通过类型检查器,它也必须在上下文中有意义。



您可能需要考虑使用整数平方根算法以获得准确性。


I have these two functions:

primes = sieve [2..] 
    where
        sieve (p:xs) = p : sieve [x|x <- xs, x `mod` p > 0]
isPrime number = number /= 1 && null [x | x <- takeWhile (\x -> x < (ceiling . sqrt) number) primes, mod number x == 0]

The thing is that when I'm trying to load module which contains those functions, I see following error message:

[2 of 2] Compiling Main             ( euler37.hs, interpreted )

euler37.hs:6:70:
No instance for (RealFrac Int)
  arising from a use of `ceiling'
Possible fix: add an instance declaration for (RealFrac Int)
In the first argument of `(.)', namely `ceiling'
In the expression: ceiling . sqrt
In the second argument of `(<)', namely `(ceiling . sqrt) number'

euler37.hs:6:80:
No instance for (Floating Int)
  arising from a use of `sqrt'
Possible fix: add an instance declaration for (Floating Int)
In the second argument of `(.)', namely `sqrt'
In the expression: ceiling . sqrt
In the second argument of `(<)', namely `(ceiling . sqrt) number'

I really can't understand what's the problem, because when I'm trying to make a small function from piece of code, which, as far as I understand, cause these errors, right in ghci, like let f number x = x < (ceiling . sqrt) number I don't see any error messages.

解决方案

The problem is that primes is a list of Integers (due to your use of mod), but sqrt operates on floating-point numbers. If you do x < (ceiling . sqrt . fromIntegral) number, then it'll work fine. fromIntegral just converts an integral number into any other numeric type:

fromIntegral :: (Integral a, Num b) => a -> b

In this case, since you don't specify any specific floating-point type to convert to, it'll default to using Double values to compute the square root. You could specify another type by changing fromIntegral to something like (fromIntegral :: Integer -> Float).

The reason you don't see this error in GHCi is because your conditional is fine; it just works on different types to the ones you're using here. Just verifying that a piece of code is correct in isolation isn't enough; for it to pass the type checker, it has to make sense in context too.

You might want to consider using an integer square root algorithm for accuracy.

这篇关于Haskell中的实例声明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆