main

Where

Let (main args)
    (MAIN.run
        Match (MAYBE.bind1 (LIST.fetch args 1) Z.read)
        | `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)
    If (n <= 1) 1 (n * (factorial1 (n - 1)))

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

Let (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 Z Package "z"