(module list_map
  (data IntList
    (doc "Singly-linked list of Int, boxed.")
    (ctor Nil)
    (ctor Cons (con Int) (con IntList)))
  (fn map_int
    (doc "Apply f to every element. Recursive on the tail.")
    (type (fn-type (params (own (fn-type (params (own (con Int))) (ret (own (con Int))))) (own (con IntList))) (ret (own (con IntList)))))
    (params f xs)
    (body (match xs
      (case (pat-ctor Nil) (term-ctor IntList Nil))
      (case (pat-ctor Cons h t) (term-ctor IntList Cons (app f h) (app map_int f t))))))
  (fn print_list
    (doc "Print each Int on its own line.")
    (type (fn-type (params (own (con IntList))) (ret (own (con Unit))) (effects IO)))
    (params xs)
    (body (match xs
      (case (pat-ctor Nil) (lit-unit))
      (case (pat-ctor Cons h t) (seq (seq (app print h) (do io/print_str "\n")) (app print_list t))))))
  (fn main
    (doc "Build [1,2,3], double each, print result.")
    (type (fn-type (params) (ret (own (con Unit))) (effects IO)))
    (params)
    (body (let xs (term-ctor IntList Cons 1 (term-ctor IntList Cons 2 (term-ctor IntList Cons 3 (term-ctor IntList Nil)))) (app print_list (app map_int (lam (params (typed x (con Int))) (ret (con Int)) (body (app * x 2))) xs))))))
