繁体   English   中英

Haskell Mini功能实现

[英]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处停止序列(如果collat​​z猜想为真,则全部执行)。

  • 过滤掉路径上的偶数元素
  • 总结一下

那么这就变成了:

  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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM