Block
    Match (Z.read (OS.fetch_arg 1))
    | 'nothing (OS.die "Expected a number argument.")
    | 'just.n
        Define (print n)
            [n -> Z.show -> STDIO.print_line]
        In
        Begin
            [n -> factorial1 -> print]
            [n -> factorial2 -> print]
            [n -> factorial3 -> print]
        End
    ;

Where

Define (factorial1 n)
    Unfold n
        If [n <= 1] 1 [n * (Fold [n - 1])]

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 OS Package "os"
Let STDIO Package "stdio"
Let Z Package "z"