我不确定这是不是很好的编程实践,但我想知道是否可以使用lambda表达式定义递归函数.
这是我编写的一个人为例子:因此可以递归地定义Haskell中的阶乘函数,如下所示
factorial :: Integer -> Integer
factorial 1 = 1
factorial (n + 1) = (n + 1) * factorial n
Run Code Online (Sandbox Code Playgroud)
现在,我想要一个f这样的功能f n = (factorial n) + 1.factorial n我想要定义f在定义中factorial n给出lambda表达式的位置,而不是使用名称(即,事先定义它)f.我可以使用递归lambda定义f代替使用名称factorial吗?
我试图模仿Sieve使用Haskell找到所有素数少于一些数.我发现其他Haskell程序以极快的速度使用Sieve方法.但是我写的下面的递归函数非常慢.代码如下
sieve' :: Integer -> Integer -> [Integer]
sieve' n 1 = [2 .. n]
sieve' n (k + 1) | [x | x <- sieve' n k, x == k + 1] == [] = sieve' n k
|otherwise = [x | x <- sieve' n k, x == k + 1 || not (mod x (k + 1) == 0)]
sieve :: Integer -> [Integer]
sieve n = sieve' n n
Run Code Online (Sandbox Code Playgroud)
筛20需要大约2分钟.在我写这个问题的时候,Sieve 30还没有完成.
任何人都可以解释为什么这个递归函数是如此缓慢.感谢您的任何帮助,您可以提供.
我正在从终端运行ghci.
在我的源文件中,我定义了
factorial :: Int -> Int
factorial n = product [1 .. n]
Run Code Online (Sandbox Code Playgroud)
当我运行它时,我得到了结果
factorial 13 = 1932053504
product [1 .. 13] = 6227020800
Run Code Online (Sandbox Code Playgroud)
对于任何小于13的数字,结果是正确的.但是,对于大于或等于12的任何数字,两个结果不一致.
另外如果我定义这个函数递归:
factorial' :: Int -> Int
factorial' 0 = 1
factorial' (n + 1) = (n + 1) * factorial' n
Run Code Online (Sandbox Code Playgroud)
我还是得到的
factorial' 13 = 1932053504
Run Code Online (Sandbox Code Playgroud)
如果您了解这里发生的事情,那将非常有帮助.谢谢
在Haskell中,我在定义函数时遇到了一些问题,因为我的参数类型与所需类型不匹配.
例如,我想编写一个函数,它接受n :: Int并生成从1到floor平方根的整数列表n.因此我会有一个功能,如:
list :: Int -> [Int]
Run Code Online (Sandbox Code Playgroud)
最初我定义的功能如下:
list :: Int -> [Int]
list n = [1 .. floor (sqrt n)]
Run Code Online (Sandbox Code Playgroud)
当我加载sript时,会出现类型不匹配的错误消息.但是,我不确定我是否不匹配sqrt函数或floor函数的类型.错误消息如下:
No instance for (Floating Int)
arising from a use of 'sqrt' at pe142.hs:6:22-27
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 expression: [1 .. floor (sqrt n)]
Failed, …Run Code Online (Sandbox Code Playgroud)