@@ -121,24 +121,40 @@ and paths_row ta ps = function
121121
122122
123123let rec_from_extyp typ label s =
124- match s with
125- | ExT ([] , t ) ->
126- let rec find_rec = function
127- | AppT (t , ts ) ->
128- let rec_t, unroll_t, roll_t, ak = find_rec t in
129- rec_t, AppT (unroll_t, ts), AppT (roll_t, ts), ak
130- | RecT (ak , unroll_t ) as rec_t ->
131- rec_t, unroll_t, rec_t, ak
132- | DotT (t , lab ) ->
133- let rec_t, unroll_t, roll_t, ak = find_rec t in
134- rec_t, DotT (unroll_t, lab), DotT (roll_t, lab), ak
135- | _ ->
136- error typ.at (" non-recursive type for " ^ label ^ " :"
137- ^ " " ^ Types. string_of_extyp s) in
138- find_rec t
139- | _ ->
124+ match try_rec_from_extyp s with
125+ | Some r -> r
126+ | None ->
140127 error typ.at (" non-recursive type for " ^ label ^ " :"
141- ^ " " ^ Types. string_of_extyp s)
128+ ^ " " ^ string_of_extyp s)
129+
130+
131+ let try_unwrap (t , zs , e ) =
132+ match t with
133+ | WrapT (ExT([] , t )) -> Some (t, zs, IL. DotE (e, " wrap" ))
134+ | _ -> None
135+
136+ let try_unroll (t , zs , e ) =
137+ try_rec_from_typ t
138+ |> Lib.Option. map (fun (unroll_t , roll_t ) ->
139+ unroll_t, zs, IL. UnrollE (e))
140+
141+ let try_peel r =
142+ try_unwrap r |> Lib.Option. orelse (fun () -> try_unroll r)
143+
144+ let avar fn r = fn r
145+
146+ let anexp fn r =
147+ match r with
148+ | ExT ([] , t ), p , zs , e ->
149+ fn (t, zs, e)
150+ |> Lib.Option. map (fun (t , zs , e ) ->
151+ ExT ([] , t), p, zs, e)
152+ | _ -> None
153+
154+ let rec fully fn pre r =
155+ match pre fn r with
156+ | None -> r
157+ | Some r -> fully fn pre r
142158
143159
144160(* Instantiation *)
@@ -416,9 +432,8 @@ Trace.debug (lazy ("[FunE] env =" ^ VarSet.fold (fun a s -> s ^ " " ^ a) (domain
416432
417433 | EL. RollE (var , typ ) ->
418434 let s, zs1 = elab_typ env typ l in
419- let rec_t, unroll_t, roll_t, ak = rec_from_extyp typ " rolling" s in
435+ let unroll_t, roll_t = rec_from_extyp typ " rolling" s in
420436 let var_t = lookup_var env var in
421- let unroll_t = subst_typ (subst [ak] [rec_t]) unroll_t in
422437 let _, zs2, f =
423438 try sub_typ env var_t unroll_t []
424439 with Sub e ->
@@ -430,7 +445,7 @@ Trace.debug (lazy ("[FunE] env =" ^ VarSet.fold (fun a s -> s ^ " " ^ a) (domain
430445 IL. RollE (IL. AppE (f, IL. VarE (var.it)), erase_typ roll_t)
431446
432447 | EL. IfE (var , exp1 , exp2 ) ->
433- let t0, zs0, ex = elab_instvar env var in
448+ let t0, zs0, ex = fully try_peel avar ( elab_instvar env var) in
434449 let _ =
435450 match t0 with
436451 | PrimT (Prim. BoolT) -> ()
@@ -449,7 +464,8 @@ Trace.debug (lazy ("[FunE] env =" ^ VarSet.fold (fun a s -> s ^ " " ^ a) (domain
449464 IL. IfE (ex, IL. AppE (f1, e1), IL. AppE (f2, e2))
450465
451466 | EL. DotE (exp1 , var ) ->
452- let ExT (aks, t), p, zs1, e1 = elab_instexp env exp1 " " in
467+ let ExT (aks, t), p, zs1, e1 =
468+ fully try_peel anexp (elab_instexp env exp1 " " ) in
453469 let tr, zs2 =
454470 match t with
455471 | StrT (tr ) -> tr, []
@@ -474,7 +490,7 @@ Trace.debug (lazy ("[DotE] s = " ^ string_of_extyp s));
474490 IL. DotE (IL. VarE (" x" ), var.it), erase_extyp s))
475491
476492 | EL. AppE (var1 , var2 ) ->
477- let tf, zs1, ex1 = elab_instvar env var1 in
493+ let tf, zs1, ex1 = fully try_peel avar ( elab_instvar env var1) in
478494Trace. debug (lazy (" [AppE] tf = " ^ string_of_norm_typ tf));
479495 let aks1, t1, s, p, zs =
480496 match freshen_typ env tf with
@@ -507,7 +523,7 @@ Trace.debug (lazy ("[AppE] ts = " ^ String.concat ", " (List.map string_of_norm_
507523 let ExT (aks, t) as s2 = freshen_extyp env s2 in
508524 aks, t, s2, zs2
509525 | _ -> error typ.at " non-wrapped type for unwrap" in
510- let t1, zs1, ex = elab_instvar env var in
526+ let t1, zs1, ex = fully try_unroll avar ( elab_instvar env var) in
511527 let s1 =
512528 match t1 with
513529 | WrapT (s1 ) -> s1
@@ -524,14 +540,13 @@ Trace.debug (lazy ("[UnwrapE] s2 = " ^ string_of_norm_extyp s2));
524540
525541 | EL. UnrollE (var , typ ) ->
526542 let s, zs1 = elab_typ env typ l in
527- let rec_t, unroll_t, roll_t, ak = rec_from_extyp typ " unrolling" s in
543+ let unroll_t, roll_t = rec_from_extyp typ " unrolling" s in
528544 let var_t = lookup_var env var in
529545 let _, zs2, f = try sub_typ env var_t roll_t [] with Sub e ->
530546 error var.at (" unrolled value does not match annotation:"
531547 ^ " " ^ Types. string_of_typ var_t ^ " "
532548 ^ " <"
533549 ^ " " ^ Types. string_of_typ roll_t) in
534- let unroll_t = subst_typ (subst [ak] [rec_t]) unroll_t in
535550 ExT ([] , unroll_t), Pure , zs1 @ zs2,
536551 IL. UnrollE (IL. AppE (f, IL. VarE (var.it)))
537552
@@ -629,7 +644,8 @@ and elab_bind env bind l =
629644 erase_extyp s))
630645
631646 | EL. InclB (exp ) ->
632- let ExT (aks, t) as s, p, zs, e = elab_instexp env exp l in
647+ let ExT (aks, t) as s, p, zs, e =
648+ fully try_peel anexp (elab_instexp env exp l) in
633649 (match t with
634650 | StrT (tr ) -> ()
635651 | InferT (z ) -> resolve_always z (StrT [] ) (* TODO: row polymorphism *)
0 commit comments