import Control.Exception
import Data.Function (fix)
-- https://en.wikibooks.org/wiki/Haskell/Denotational_semantics
g :: (Integer -> Integer) -> (Integer -> Integer)
g x = \n -> if n == 0 then 1 else n * x (n - 1)
x0 :: Integer -> Integer
x0 = undefined
(f0:f1:f2:f3:_) = [x0,g(x0),g(g(x0)),g(g(g(x0)))] -- iterate g x0
fit (name, f) i = 
  handle 
    handler 
    (do 
      putStrLn $ funcName ++ show (f i)
      fit (name, f) (i + 1)
    )
  where
    handler :: SomeException -> IO ()
    handler ex = putStrLn $ "undefined\n"
    
    funcName = name ++ "(" ++ (show i) ++ ") = "
factorial = fix g
main = do 
    mapM_ (flip fit 0) $ take 10 (map (\i -> "f" ++ show i) [0..]) `zip` iterate g x0
    print $ factorial 10