Skip to content

Commit

Permalink
Feat: Introduce NSet.flatten
Browse files Browse the repository at this point in the history
The goal is to have a more advance implementation of Type.tuple
  • Loading branch information
FardaleM committed Oct 9, 2024
1 parent 38a36eb commit 34fbbc3
Showing 1 changed file with 47 additions and 2 deletions.
49 changes: 47 additions & 2 deletions lib/common/Type.ml
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ and NSet : sig
val add : elt -> t -> t
val fold : (elt -> 'a -> 'a) -> t -> 'a -> 'a
val map : (elt -> elt) -> t -> t
val flatten : t -> t
val pp : elt Fmt.t -> t Fmt.t
end = struct
type elt = Base.t
Expand Down Expand Up @@ -229,6 +230,51 @@ end = struct
let fold fn t acc = CCArray.fold_left (CCFun.flip fn) acc t
let map fn t = of_iter @@ Iter.map fn @@ to_iter t

let flatten a =
let size, t_list =
let size, toplevel, nested =
Array.fold_left
(fun (size, toplevel, nested) e ->
match e with
| Base.Tuple elts ->
let elts : elt array = Obj.magic elts in
if length elts = 0 then (size, toplevel, nested)
else (length elts + size, toplevel, (ref 0, elts)::nested)
| t -> (1 + size, t :: toplevel, nested)
) (0, [], []) a
in
match toplevel with
| [] -> size, nested
| _ -> size, (ref 0, Array.of_list (List.rev toplevel))::nested
in
match t_list with
| [] -> empty
| [ _, a ] -> a
| _ ->
let t = Array.make size (Base.Constr (Longident.Lident "__dummy", [||])) in
let rec loop pos = function
| [] -> assert (pos = size)
| [ (i, a) ] ->
assert (pos = size - (length a - !i)); if !i < length a then Array.blit a !i t pos (length a - !i)
| (i, a) :: tl ->
if !i = length a then loop pos tl
else
let idx, e, tl =
List.fold_left
(fun (idx, e, tl) (i, a) ->
if !i = length a then (idx, e, tl)
else
if Base.compare a.(!i) e < 0 then (i, a.(!i), (i, a) :: tl)
else (idx, e, (i, a) :: tl)
) (i, a.(!i), []) tl
in
incr idx;
t.(pos) <- e;
loop (pos + 1) ((i, a) :: tl)
in
loop 0 t_list;
t

let pp pp_ty ppf = function
| [||] -> Fmt.string ppf "unit"
| [| elt |] -> pp_ty ppf elt
Expand Down Expand Up @@ -299,8 +345,7 @@ let arrow env param ret =
| _, _ -> Arrow (NSet.singleton param, ret)

let tuple env elts =
let aux = function Tuple elts -> elts | elt -> NSet.singleton elt in
let elts = NSet.fold (fun elt -> NSet.union @@ aux elt) elts NSet.empty in
let elts = NSet.flatten elts in
hashcons env
@@ match NSet.is_singleton elts with Some elt -> elt | None -> Tuple elts

Expand Down

0 comments on commit 34fbbc3

Please sign in to comment.