exu*_*ero 5 haskell function definition
我正在学习Haskell,我正在尝试编写一个函数来返回一个数字的因子列表.这就是我所拥有的:
factors :: Int -> [Int]
factors n = [x | x <- [2..s], n `mod` x == 0]
where s = floor (sqrt n)
Run Code Online (Sandbox Code Playgroud)
当我尝试加载模块时ghci,我收到两个错误,
p003.hs:3:14:
No instance for (RealFrac Int)
arising from a use of `floor' at p003.hs:3:14-27
Possible fix: add an instance declaration for (RealFrac Int)
In the expression: floor (sqrt n)
In the definition of `s': s = floor (sqrt n)
In the definition of `factors':
factors n = [x | x <- [2 .. s], n `mod` x == 0]
where
s = floor (sqrt n)
p003.hs:3:21:
No instance for (Floating Int)
arising from a use of `sqrt' at p003.hs:3:21-26
Possible fix: add an instance declaration for (Floating Int)
In the first argument of `floor', namely `(sqrt n)'
In the expression: floor (sqrt n)
In the definition of `s': s = floor (sqrt n)
Failed, modules loaded: none.
Run Code Online (Sandbox Code Playgroud)
有什么建议?
Chr*_*ith 10
参数具有类型Int,因此您无法为其计算平方根.您需要先将其转换为浮点类型,您可以使用fromIntegral.与其他一些语言不同,Haskell不会自动将整数提升为浮点数(也不会进行任何其他自动类型转换).
所以sqrt n改为sqrt (fromIntegral n).
sqrt功能的类型是
sqrt :: (Floating a) => a -> a
Run Code Online (Sandbox Code Playgroud)
你可以输入:t sqrtghci 来检查这个.
Int不是一个实例Floating,这就是你看到第二个错误的原因.
第一个错误的原因是一样的; 检查:t floor显示类型是:
floor :: (RealFrac a, Integral b) => a -> b
Run Code Online (Sandbox Code Playgroud)
该函数期待一个实例RealFrac,并且您正在提供Int.
键入:info RealFrac或:info Floating显示两者都没有实例Int,这就是错误主体所说的原因
没有实例... Int
解决这个问题的方法是确保类型正确; 他们必须是正确类型类的成员.
一个简单的方法是使用fromIntegral函数,:t显示类型:
fromIntegral :: (Integral a, Num b) => a -> b
Run Code Online (Sandbox Code Playgroud)
使用fromIntegral是必要的,因为进入的类型是Int,但功能floor和sqrt对类型进行操作RealFrac,并Floating分别.
这是允许的,因为从类型签名中可以看出,它fromIntegral返回的实例Num包括RealFrac和Floating类型.您可以通过键入:info Num和:info Float输入ghci并查看输出来说服自己.
对他的程序进行更改将得到以下最终结果,该结果可以按您的要求工作:
factors :: Int -> [Int]
factors n = [x | x <- [2..s], n `mod` x == 0]
where s = floor (sqrt $ fromIntegral n)
Run Code Online (Sandbox Code Playgroud)
有两个很好的资源可以准确理解正在发生的事情是Haskell教程关于Type Classes和Numbers的部分.