newtype Mu a = Roll
  { unroll :: Mu a -> a }

fix :: (a -> a) -> a
fix = g <*> (Roll . g)
  where
    g = (. (>>= id) unroll)

- this version is not in tail call position...





fac :: Integer -> Integer
fac =
  (fix $ \f n i -> if i <= 0 then n else f (i * n) (i - 1)) 1








fibs :: () -> [Integer]
fibs() = 0: 1: fix fibs_ 0 1
  where
    fibs_ fnc f s =
      case f + s of n -> n `seq` n: fnc s n

main :: IO ()
main =
  mapM_
    print
    [ map fac [1 .. 20]
    , take 20 $ fibs()
    ]