[英]Haskell Mini Function Implementation
我一直在尝试使用这个函数并使用iterate和takeWhile进行小的实现。 它不必使用这些功能,我只是想把它变成一行。 我可以在其中看到模式,但我似乎无法在没有基本上生成相同代码的情况下利用它,只需使用迭代而不是递归。
fun2 :: Integer -> Integer
fun2 1 = 0
fun2 n
| even n = n + fun2 (n `div` 2)
| otherwise = fun2 (3 * n + 1)
任何帮助都会很棒。 几个小时以来我一直在努力。 谢谢
如果你想用iterate
做到这一点,关键是把它砍成更小的逻辑部分:
使用规则生成序列
如果k均匀,则k + 1 = k / 2
如果k奇数,则k + 1 = 3a k +1
在j = 1处停止序列(如果collatz猜想为真,则全部执行)。
那么这就变成了:
f = sum . filter even . takeWhile (>1) . iterate (\n -> if even n then n `div` 2 else 3*n + 1)
但是,我确实认为使用辅助函数会更清楚
f = sum . filter even . takeWhile (>1) . iterate collatz
where collatz n | even n = n `div` 2
| otherwise = 3*n + 1
这可能不会为您节省任何行,但会将您的递归转换为数据生成。
首先,我同意汤姆的评论,即你的四行版本没有任何问题。 它完全可读。 但是,将Haskell函数转换为一个衬里偶尔会很有趣。 谁知道,你可能会学到一些东西!
目前你有
fun 1 = 0
fun n | even n = n + fun (n `div` 2)
| otherwise = fun (3 * n + 1)
您始终可以使用警卫将表达式转换为if
fun 1 = 0
fun n = if even n then n + fun (n `div` 2) else fun (3 * n + 1)
您始终可以将一系列模式匹配转换为案例表达式:
fun n = case n of
1 -> 0
_ -> if even n then n + fun (n `div` 2) else fun (3 * n + 1)
最后,您可以将case表达式转换为if
的链(实际上,通常这需要一个Eq
实例作为函数的参数,但是因为你使用的是Integer
,所以无关紧要)。
fun n = if n == 1 then 0 else if even n then n + fun (n `div` 2) else fun (3 * n + 1)
我想你会同意这比你开始时的可读性差得多。
一个班轮;)
fun2 n = if n==1 then 0 else if even n then n + fun2 (n `div` 2) else fun2 (3 * n + 1)
我的感觉是缺少查找表,没有递归就无法实现这个函数,因为在递归中传递的参数似乎是不可预测的(除了n为2的幂)。
另一方面,横冲直撞帮助我学到了新东西。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.