Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 在递归函数的最终结果上做一些事情,在同一个函数中_Haskell_Recursion - Fatal编程技术网

Haskell 在递归函数的最终结果上做一些事情,在同一个函数中

Haskell 在递归函数的最终结果上做一些事情,在同一个函数中,haskell,recursion,Haskell,Recursion,说起来容易,解释起来难。我有一个很小的函数,可以从基数10进行基数转换: demode 0 _ = [] demode n b = m:(demode d b) where (d, m) = divMod n b 所以,如果我们想知道如何在基9中写28,解调289=[1,3]。 但是,当然,我们必须颠倒列表,使它看起来像一个31。 这可以通过创建一个调用“demome”的函数来实现,然后将其结果反转,但是由于Haskell非常酷,因此可能有一种更优雅的方式来表示“在最终情况下(demome

说起来容易,解释起来难。我有一个很小的函数,可以从基数10进行基数转换:

demode 0 _ = [] 
demode n b = m:(demode d b)
 where (d, m) = divMod n b
所以,如果我们想知道如何在基9中写28,解调289=[1,3]。 但是,当然,我们必须颠倒列表,使它看起来像一个31。 这可以通过创建一个调用“demome”的函数来实现,然后将其结果反转,但是由于Haskell非常酷,因此可能有一种更优雅的方式来表示“在最终情况下(demome 0),将所有内容附加到列表中,然后反转列表”


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

没有。您唯一的希望是使用helper函数。请注意,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
作为“worker”的缩写)

这两种情况都可以从学习使用高阶函数进行递归中获益


总的来说,在Haskell中尝试“在一个函数中完成所有任务”有点不好;Haskell风格是围绕着将问题划分为多个部分,使用单独的函数解决问题,并将结果函数组合在一起而构建的;特别是如果这些函数在其他地方也有用的话(这种情况发生的频率比你想象的要高)。

与你的问题无关,但我认为你的
demode
被破坏了:什么是
demode 9
?(顺便说一句,像这样的角落案例是很好的测试案例)。使用调用
demome
并返回相反结果的外部函数怎么样?demome 9=[0,1]>10,不是很好吗?关于外部功能:我想到了,我在上面提到过。当然,对于这种情况来说,这很简单,也足够好,但在其他一些情况下,它会很有用。另外,提高haskell语法也不坏。谢谢!但是“Haskell确实允许您在where子句中定义函数(至少现在是这样)”是什么意思呢?将来有没有计划禁止它们呢?这让我害怕,我喜欢where条款的灵活性,它让一切变得更干净、更容易。@AsímoullóJosetustra-主要是这样说的。想必如果在
where
子句中使用帮助函数的人太少,那么它最终也会被删除。@jcast,当像西蒙·佩顿·琼斯这样技术娴熟、经验丰富的人说类型系统太复杂而无法调试时,很可能是这样。在HM中,Let泛化是免费的,但在格拉斯哥-哈斯克尔(Glasgow-Haskell)中,它很昂贵,而且(因为有作用域类型变量可用)不值得。正如我所说,您不必担心
where
子句中的函数——它们就在这里。