You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

59 lines
1.7 KiB

module Fibs where
fibs :: [Integer]
fibs = 1 : scanl (+) 1 fibs
-- To understand how this works, let's expand fibs, but first
-- the definition of scanl
--
scanl' :: (a -> b -> a) -> a -> [b] -> [a]
scanl' f q ls =
q : (case ls of
[] -> []
x:xs -> scanl' f (f q x) xs)
-- Now on to the expansion, replace fibs with it's definition
fibs1 :: [Integer]
fibs1 = 1 : scanl (+) 1 (1 : scanl (+) 1 fibs)
-- Apply definition of scanl
fibs2 :: [Integer]
fibs2 = 1 : (1 : scanl (+) 2 (scanl (+) 1 fibs))
-- As you can see we've constructed another element of the list
-- If we continue, we'll generate another one, but before we can do this
-- we have to repalce fibs with it's definition again.
-- Note: all fibs's are the same so you replace another fibs instead
fibs3 :: [Integer]
fibs3 = 1 : (1 : scanl (+) 2 (scanl (+) 1
(1 : scanl (+) 1 fibs)))
-- Apply the definition of the second scanl
fibs4 :: [Integer]
fibs4 = 1 : (1 : scanl (+) 2 (1 : scanl (+) 2 (scanl (+) 1 fibs)))
-- Apply the definition of the first scanl
fibs5 :: [Integer]
fibs5 = 1 : (1 : (2 : (scanl (+) 3 (scanl (+) 2 (scanl (+) 1 fibs)))))
-- We have now generated the first 3 elements of the fibonacci series
-- If the same replacements are being applied, it will keep generating
-- new entries.
fibsN :: Int -> Integer
fibsN = (!!) fibs
-- 1
fibs' :: [Integer]
fibs' = take 20 $ fibs
-- 2
fibs'' :: [Integer]
fibs'' = takeWhile (<100) fibs
-- 3
fact :: [Integer]
fact = scanl (*) 1 [1..]
factN :: Int -> Integer
factN = (!!) fact