在递归函数的最终结果上执行某些操作,同样的函数

时间:2015-08-07 15:00:14

标签: haskell recursion

更容易展示而不是解释。我有这个微小的功能来从基数10进行基本转换:

demode 0 _ = [] 
demode n b = m:(demode d b)
 where (d, m) = divMod n b

所以,如果我们想看看我们如何在基数9中写28,则demode 28 9 = [1,3]。 但是,当然,我们必须将列表反转,使其看起来像31。 这可以通过创建一个调用'demode'然后反转结果的函数来轻松实现,但是Haskell非常酷,所有这些都可能是一种更优雅的方式来说“在最后的情况下(demode 0 _),附加一切到列表然后反转列表“。

请注意,基本转换只是我用来说明问题的一个例子,真正的问题是如何将最终转换应用于递归函数的最后结果。

1 个答案:

答案 0 :(得分:1)

不。你唯一的希望就是使用辅助函数。请注意,Haskell 确实允许您在where子句中定义函数(至少目前为止),因此在单独的顶部意义上不必是“单独的函数”级定义。你基本上有两种选择:

添加累加器并完成你想做的任何工作:

demode n b = w n [] where
    w 0 xn = reverse xn
    w n xn = w d (xn ++ [m]) where
        (d, m) = divMod n b

希望你可以按照这样做的方式,但请注意,在这种情况下,你最好不要说

demode n b = w n [] where
    w 0 xn = xn
    w n xn = w d (m : xn) where
        (d, m) = divMod n b

以相反的顺序构建列表并返回该列表。

将常规定义向下推送到辅助函数,并将该函数包装到您想要的任何工作中:

demode n b = reverse (w n) where
    w 0 = []
    w n = m : w d where
        (d, m) = divMod n b

(在所有三个例子中,我都使用术语w作为“工人”的简称。)

任何一种情况通常都可以从学习使用高阶函数进行递归中获益。

一般来说,在Haskell中尝试做“一切功能”的风格有点糟糕; Haskell风格是围绕将问题分成多个部分,解决具有单独功能的部分,并将结果函数组合在一起而构建的; 尤其是,如果这些功能在其他地方也会有用(这种情况的发生频率超出你的想象)。