更容易展示而不是解释。我有这个微小的功能来从基数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 _),附加一切到列表然后反转列表“。
请注意,基本转换只是我用来说明问题的一个例子,真正的问题是如何将最终转换应用于递归函数的最后结果。
答案 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风格是围绕将问题分成多个部分,解决具有单独功能的部分,并将结果函数组合在一起而构建的; 尤其是,如果这些功能在其他地方也会有用(这种情况的发生频率超出你的想象)。