open Necromonads

module IMap = Map.Make(Int)

module type TYPE = sig
  type value
  type loc = int
  type heap = value IMap.t * int
end

module Spec (M:MONAD) = struct
  let initialHeap = (IMap.empty, 0)
  let alloc v = M.ret (fun (h,i) -> M.ret (i, (IMap.add i v h, i+1)))
  let read l = M.ret (fun (h,i) -> match IMap.find_opt l h with
      | Some v -> M.ret (v, (h,i))
      | None -> M.fail "Unbound location")
  let write (l,v) = M.ret (fun (h,i) -> M.ret ((), (IMap.add l v h, i)))
end