packages feed

alms-0.5.0: examples/ex27-focusing-and-adoption.alms

(* Demonstrates Pottier's (2007) version of adoption/focus
   (Faehnrich and DeLine, 2002). *)

(* Some affine list operations. *)

(*
  type variables:
    `a                 stored value
    't                  region name

  variables:
    x, y: `a           stored value
    xs: `a list        region representation

  T[[ { p |-> t } ]]     = (p, T[[ t ]]) region1
  T[[ { p |->^w t } ]]   = (p, T[[ t ]]) region
  T[[ Ptr t ]]           = T[[ t ]] ptr

*)

let length[`a] (xs: `a list) : int * `a list =
  foldr (fun (x: `a) (n: int, xs: `a list) ->
           (n + 1, Cons (x, xs)))
        (0, Nil[`a]) xs

let snoc[`a] (x: `a) |[a] (xs: `a list) : `a list =
  foldr (fun (x: `a) (xs: `a list) -> Cons (x, xs))
        (Cons (x, Nil[`a])) xs

let revAppN =
  let rec loop[`a] (n: int) (xs: `a list) |[a] (acc: `a list)
                    : `a list * `a list =
        match n with
        | 0 -> (acc, xs)
        | _ -> match xs with
               | Cons(x, xs) -> loop (n - 1) xs (Cons (x, acc))
               | xs          -> (acc, xs)
  in loop

let rev[`a] (xs: `a list) : `a list =
  let (_, acc) = revAppN (-1) xs Nil[`a] 
   in acc

let swapN[`a] (ix: int) (y: `a) |[a] (xs: `a list)
       : `a * `a list =
  let (Cons(x, xs), acc) = revAppN ix xs Nil[`a] in
  let (xs, _) = revAppN (-1) acc (Cons (y, xs)) in
    (x, xs)

module Region : sig
  type ('t, `a) region : A
  type ('t, `a) region1 : A
  type 't ptr

  val newRgn    : unit -> ex 't. ('t,`a) region
  val mallocIn  : ('t,`a) region -> `a -o 't ptr * ('t,`a) region
  val swap      : ('t,`a) region -> 't ptr -o `a -o `a * ('t,`a) region
  val malloc    : unit -> ex 't. ('t,unit) region1 * 't ptr
  val free      : ('t,`a) region1 -> unit
  val adopt     : ('t1,`a) region -> ('t2,`a) region1 -o 't2 ptr -o
                  't1 ptr * ('t1,`a) region
  val focus     : ('t,`a) region -> 't ptr -o
                  ex 't1. ('t1,`a) region1 * 't1 ptr *
                          (('t1,`a) region1 -o ('t,`a) region)
end = struct
  type ('t, `a) region = `a list
  type ('t, `a) region1 = `a
  type 't ptr = int

  let newRgn () = Nil

  let freeRgn _ = ()

  let mallocIn (xs: `a list) (a: `a) =
    let (ix, xs) = length xs in
      (ix, snoc a xs)

  let swap (xs: `a list) (ix: 't ptr) (x: `a) =
    let (y, xs) = swapN ix x xs in
      (y, xs)

  let malloc () = ((), 0)

  let swap1 (x: `a) _ (y: `b) = (x, y)

  let free _ = ()

  let adopt (rgn: `a list) (x: `a) _ =
    mallocIn rgn x

  let focus (xs: `a list) (ix: 't ptr) =
     let (Cons (x, xs), acc) = revAppN ix xs Nil in
       (x, 0, fun (y: `a) -> fst (revAppN (-1) acc (Cons (y, xs))))
end