Haskell Fibonacci 函数的良好风格

Joh*_*erg 2 haskell anonymous-function fibonacci

我只是在学习 Haskell 并尝试实现一个函数来获取包含前 N 个斐波那契数的列表:

fibonacci :: Integer -> [Integer]
fibonacci 1 = [0]
fibonacci 2 = fibonacci 1 ++ [1]
fibonacci n = appendSumOfLastTwo (fibonacci (n - 1))

appendSumOfLastTwo :: (Num a) => [a] -> [a]
appendSumOfLastTwo xs = xs ++ [addLastTwo xs]

addLastTwo :: (Num a) => [a] -> a
addLastTwo xs = last xs + (xs !! ((length xs) - 2))
Run Code Online (Sandbox Code Playgroud)

这有效但不是很漂亮,因为它需要两个名称奇怪的辅助函数。在 Haskell 中,有这样一个单独使用的函数是常见的吗?

为了摆脱这些函数,我尝试了匿名函数:

fibonacci :: Integer -> [Integer]
fibonacci 1 = [0]
fibonacci 2 = fibonacci 1 ++ [1]
fibonacci n = (\xs -> xs ++ [(\xs -> last xs + (xs !! ((length xs) - 2))) xs]) (fibonacci ( n - 1))
Run Code Online (Sandbox Code Playgroud)

但这并没有好多少,因为它几乎完全不可读。

大家会怎么想?我怎样才能最好地构建我的代码?

kar*_*kfa 5

你不能比这更漂亮

fibs = 1:1:zipWith (+) fibs (tail fibs)
Run Code Online (Sandbox Code Playgroud)

并用作任何 n

take n fibs
Run Code Online (Sandbox Code Playgroud)

或者,如果您想从基础实现,也许最好先定义第 n 个斐波那契数

fib 1 = 1
fib 2 = 1                                      
fib n = fib (n-1) + fib (n-2)
Run Code Online (Sandbox Code Playgroud)

这个系列将很简单

map fib [1..n]
Run Code Online (Sandbox Code Playgroud)

请注意,对于任何大的 n,性能都会很糟糕。