【发布时间】:2013-04-21 16:40:11
【问题描述】:
我正在写作业(CIS194 Haskell 课程)。
我必须将下面的递归函数重写为管道函数(没有明显的递归)。
fun2 :: Integer -> Integer
fun2 1 = 0
fun2 n
| even n = n + fun2 ( n ‘div‘ 2 )
| otherwise = fun2 (3 * n + 1)
我的第一次尝试在这里:
fun2''' = sum
. (filter (even))
. unfoldr (\x -> if (even x)
then Just (x, x `div` 2)
else if (x==1) then Nothing
else Just (x, x * 3 + 1))
这是一个正常的解决方案还是很奇怪?
我怎样才能更好地重写fun2?
现在我尝试使用takeWhile 和iterate 编写版本
我的第二次尝试:
fun2'' :: Integer -> Integer
fun2'' = sum
. (filter even)
. takeWhile (/=1)
. iterate (\x -> if even x
then x `div` 2
else x * 3 + 1 )
我现在对until 版本没什么问题。
【问题讨论】:
-
一些不必要的括号,但还算不错。我很乐观,您的
takeWhile+iterate方法也会取得不错的效果。 -
对于奇怪的情况,您也可以返回
Just (0, x * 3 + 1),而不是返回x,然后避免filter。 -
应用 Collatz 猜想并写成 fun2 _ = 0 怎么样
-
@LukaRahne 它不是 0。该函数将给定数字的 Collatz 序列中的所有偶数相加。该猜想表明它是有限的,因此它必须以 2 的幂序列结束,即偶数(直到最后的 1)。
标签: haskell recursion pointfree pipelined-function