{
: file_create
: file_open
: file_close
: file_write
: file_write_byte
: file_read_all
: die
: run
: pure
: bind1
: lift1
: lift2
: sequence2
: sequence3
: compose
: read_file
: print_line
}

Where

Define (read_file file_name)
    (bind1 (file_open file_name)
        Func {file}
            (lift2 (file_read_all file) (file_close file)
                Func {text _} text))

Where

Define (print_line text)
    Func {}
        (STDIO.print_line text)

Define (file_create name)
    Func {} (Prim file_create name)

Define (file_open name)
    Func {} (Prim file_open name)

Define (file_close file)
    Func {} (Prim file_close file)

Define (file_write file string)
    Func {} (Prim file_write file string)

Define (file_write_byte file byte)
    Func {} (Prim file_write_byte file byte)

Define (file_read_all file)
    Func {} (Prim file_read_all file)

Define (die message)
    Func {} (Prim die message)

Where

Define (run m)
    (m)

Define (pure x)
    Func {} x

Define (bind1 m1 f)
    Func {}
        Let m2 (f (m1))
        In
        (m2)

Define (lift1 m1 f)
    Func {}
        Let x1 (m1)
        In
        (f x1)

Define (lift2 m1 m2 f)
    Func {}
        Let x1 (m1)
        Let x2 (m2)
        In
        (f x1 x2)

Define (sequence2 m1 m2)
    Func {}
        Begin (m1) (m2) End

Define (sequence3 m1 m2 m3)
    Func {}
        Begin (m1) (m2) (m3) End

Define (compose f g)
    Func {x1}
        Func {}
            Let m1 (f x1)
            In
            Let x2 (m1)
            In
            Let m2 (g x2)
            In
            (m2)

Where

Let STDIO Package "stdio"