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

Where

Let (read_file file_name)
    (bind1 (file_open file_name)
        Func file.
            (lift2 (file_read_all file) (file_close file)
                Func text _. text))

Where

Let (print_line text)
    Func _.
        (STDIO.print_line text)

Let (file_create name)
    Func _. (Prim file_create name)

Let (file_open name)
    Func _. (Prim file_open name)

Let (file_close file)
    Func _. (Prim file_close file)

Let (file_write file string)
    Func _. (Prim file_write file string)

Let (file_read_all file)
    Func _. (Prim file_read_all file)

Let (die message)
    Func _. (Prim die message)

Where

Let (run m)
    Do (m {})
    In
    {}

Let (pure x)
    Func _. x

Let (bind1 m1 f)
    Func _.
        Let m2 (f (m1 {}))
        In
        (m2 {})

Let (lift1 m1 f)
    Func _.
        Let x1 (m1 {})
        In
        (f x1)

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

Let (sequence2 m1 m2)
    Func _.
        Do (m1 {})
        Do (m2 {})
        In
        {}

Let (sequence3 m1 m2 m3)
    Func _.
        Do (m1 {})
        Do (m2 {})
        Do (m3 {})
        In
        {}

Let (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"