(module mrb_1_histogram
  (fn fill
    (doc "Fill an Int RawBuf at indices i..n with the running value v, stepping v by 7 each slot. own->own threading: the buffer is consumed and returned per RawBuf.set, so the recursion re-binds buf each step.")
    (type (fn-type
      (params (own (con RawBuf (con Int))) (own (con Int)) (own (con Int)) (own (con Int)))
      (ret (own (con RawBuf (con Int))))))
    (params buf i n v)
    (body
      (if (app eq i n)
        buf
        (tail-app fill (app RawBuf.set buf i v) (app + i 1) n (app + v 7)))))
  (fn sum
    (doc "Read back indices i..n of a borrow-mode RawBuf and total them. Reader: receiver is borrowed, never consumed.")
    (type (fn-type
      (params (borrow (con RawBuf (con Int))) (own (con Int)) (own (con Int)) (own (con Int)))
      (ret (own (con Int)))))
    (params buf i n acc)
    (body
      (if (app eq i n)
        acc
        (tail-app sum buf (app + i 1) n (app + acc (app RawBuf.get buf i))))))
  (fn main
    (doc "Allocate a 5-slot Int RawBuf, fill it (0,7,14,21,28), then sum it back and print 70.")
    (type (fn-type (params) (ret (own (con Unit))) (effects IO)))
    (params)
    (body
      (let buf (new RawBuf (con Int) 5)
        (let buf (app fill buf 0 5 0)
          (app print (app sum buf 0 5 0)))))))
