Block
    Let arg (OS.fetch_arg 1)
    In
    (MAIN.run
        Match (Z.read arg)
        | 'nothing (MAIN.die "Expected a number argument.")
        | 'just.n
            (MAIN.sequence3
                (MAIN.print_line (Z.show (factorial1 n)))
                (MAIN.print_line (Z.show (factorial2 n)))
                (MAIN.print_line (Z.show (factorial3 n))))
        ;)

Where

Define (factorial1 n)
    Define (rec rec n)
        If [n <= 1] 1 [n * (rec rec [n - 1])]
    In
    (rec rec n)

Define (factorial2 n)
    Iterate {f m} From {1 2}
        If [m > n]
            f
            Continue {[f * m] [m + 1]}

Define (factorial3 n)
    (Z.fold n 1
        Func {m mfact} [[m + 1] * mfact])

Where

Let LIST Package "list"
Let MAIN Package "main"
Let MAYBE Package "maybe"
Let OS Package "os"
Let Z Package "z"