Hatena::Groupcadr

kozima の日記

2009-06-01

alist <-> plist を OCaml で

| 23:14

CL できれいにしたバージョンを書いたのですが、説明を書こうとしたら混乱したので、頭の中を整理するために OCaml で書いてみました。

type sexp = Atom of string | Cons of place * place
and place = sexp ref

let rec alist_to_plist = function
  | Atom _ as x -> x
  | Cons (aux, rest) as whole ->
      ignore (alist_to_plist !rest);
      match !aux with Cons (key, value) as a ->
        aux := !key; key := !value; value := !rest; rest := a;
        whole

let rec plist_to_alist = function
  | Atom _ as x -> x
  | Cons (key, aux) as whole ->
      match !aux with Cons (value, rest) as a ->
        ignore (plist_to_alist !rest);
        aux := !rest; rest := !value; value := !key; key := a;
        whole

let cons a d = Cons (ref a, ref d)
let acons key value rest = cons (cons key value) rest
let pcons key value rest = cons key (cons value rest)

let alist = acons (Atom "bar") (Atom "2") (acons (Atom "foo") (Atom "1") Atom "nil") in
let plist = pcons (Atom "bar") (Atom "2") (pcons (Atom "foo") (Atom "1") Atom "nil") in
  alist_to_plist alist = plist

let alist = acons (Atom "bar") (Atom "2") (acons (Atom "foo") (Atom "1") Atom "nil") in
let plist = pcons (Atom "bar") (Atom "2") (pcons (Atom "foo") (Atom "1") Atom "nil") in
  plist_to_alist plist = alist

値と場所の区別重要。ということを意識するために参照を使用。静的型付言語は思考の整理の道具になるんじゃないかと思うことがあります。