我不打算讨论算法本身,但这里有一些关于如何构造递归函数的建议。
首先,这是在单独的文件中格式化代码的方法
fibo :: Integral x => [x]->x->x->x->[x]
fibo l x y 0 = l
fibo l x y n = fibo (l ++ [y+x] ++ [y+x+y]) (x+y) (y+x+y) (n-1)
如果您将其保存为 fibo.hs,那么您可以使用以下命令启动 GHCi
ghci fibo.hs
在开始时加载文件。也可以在启动 GHCi 后使用命令加载文件
:l fibo.hs
(假设您在保存 fibo.hs 的同一目录中启动 GHCi)
另一个不错的功能是,现在当您编辑文件时,您只需输入即可重新加载所有更改
:r
在 GHCi 提示符中。
现在,为了摆脱额外的参数,Haskell 中的常用模式是将递归部分重构为它自己的辅助函数,并将 main 函数作为只接受必要参数的入口点。例如,
fibo :: Integral x => x -> [x]
fibo n = fiboHelper [0,1] 0 1 n
fiboHelper :: Integral x => [x]->x->x->x->[x]
fiboHelper l x y 0 = l
fiboHelper l x y n = fiboHelper (l ++ [y+x] ++ [y+x+y]) (x+y) (y+x+y) (n-1)
现在您可以fibo
简单地调用
> fibo 3
[0,1,1,2,3,5,8,13]
此外,像这样本身无用的辅助函数通常作为内部函数隐藏在主函数中,使用let
or where
。
fibo :: Integral x => x -> [x]
fibo n = fiboHelper [0,1] 0 1 n where
fiboHelper l x y 0 = l
fiboHelper l x y n = fiboHelper (l ++ [y+x] ++ [y+x+y]) (x+y) (y+x+y) (n-1)
像这样的内部函数通常被赋予一个较短的名称,因为上下文清楚地说明了它的用途,所以我们可以将名称更改为 eg fibo'
。
go
是递归辅助函数的另一个常用名称。