{-# LANGUAGE Safe #-}
module Data.InfList.Common
( nats
, nats1
, evens
, odds
, fibs
, lucas
, facts
, pascalTriangle
, bells
, collatz
) where
import Data.InfList as I
-- Where is the idiomatic Haskell Nat type?
nats = I.iterate succ 0
nats1 = I.iterate succ 1
evens = I.iterate (+2) 0
odds = I.iterate (+2) 1
fibs = 0 ::: 1 ::: I.zipWith (+) fibs (I.tail fibs)
lucas = 2 ::: 1 ::: I.zipWith (+) lucas (I.tail lucas)
facts = 1 ::: I.mapAccumL (\prev i -> let i' = prev * i in (i',i')) 1 nats1
-- http://www.polyomino.f2s.com/david/haskell/hs/CombinatoricsCounting.hs.txt
nextPascal prev = Prelude.zipWith (+) ([0] ++ prev) (prev ++ [0])
pascalTriangle = I.iterate nextPascal [1]
bells = 1 ::: doBells ([1],[1]) where
doBells (cs,bs) = b ::: doBells (cs',b:bs) where
cs' = nextPascal cs
b = sum (Prelude.zipWith (*) cs bs)
-- find one that doesn't contain 1!
collatz = I.iterate hotpo where
hotpo n = let (half,rem) = divMod n 2 in if rem == 0 then half else n*3 + 1