@@ -153,6 +153,24 @@ let extract_bind infer_binds env tr1 l t2 =
153153 | None -> raise (Sub (Struct (l, Missing )))
154154 | Some (t , zs , e ) -> t, zs, fun f _ _ -> IL. AppE (f, e)
155155
156+ let rec has_typs_typ ps = function
157+ | StrT (tr ) -> List. exists (fun (_ , t ) -> has_typs_typ ps t) tr
158+ | FunT (aks , td , ExT(_ , tr ), e ) ->
159+ (match e with
160+ | Implicit | Explicit Pure ->
161+ has_typs_typ (List. map (fun p -> AppT (p, varTs aks)) ps) tr
162+ | Explicit Impure -> false )
163+ | TypT (ExT(_ , p )) -> List. mem p ps
164+ | VarT (_)
165+ | PrimT (_)
166+ | WrapT (_)
167+ | LamT (_)
168+ | AppT (_)
169+ | TupT (_)
170+ | DotT (_)
171+ | RecT (_)
172+ | InferT (_ ) -> false
173+
156174let resolve_typ z t =
157175 Trace. sub (lazy (" [resolve_typ] z = " ^ string_of_norm_typ (InferT (z))));
158176 Trace. sub (lazy (" [resolve_typ] t = " ^ string_of_norm_typ t));
@@ -174,6 +192,24 @@ let rec sub_typ infer_binds env t1 t2 ps =
174192 Trace. sub (lazy (" [sub_typ] t2 = " ^ string_of_norm_typ t2));
175193 Trace. sub (lazy (" [sub_typ] ps = " ^
176194 String. concat " , " (List. map string_of_norm_typ ps)));
195+ let ts', zs', t2, ps =
196+ if ps <> [] then
197+ let su, zs' = match_typ env t1 t2 ps in
198+ Trace. sub (lazy (" [sub_typ] su = " ^
199+ String. concat " , " (List. map (fun (p , t ) -> Printf. sprintf " [= %s] - [= %s]\n " (string_of_typ p) (string_of_typ t)) su)));
200+ let t2 = subst_typ (List. map (fun (p , t ) -> psubst p t) su) t2 in
201+ let ps' = List. filter (fun p -> List. mem_assoc p su) ps in
202+ let ts' = List. map (fun p -> List. assoc p su) ps' in
203+ let ps = List. filter (fun p -> not (List. mem_assoc p su)) ps in
204+ if ps <> [] then begin
205+ Trace. sub (lazy (" [sub_typ] unmatched ps = " ^
206+ String. concat " , " (List. map string_of_norm_typ ps)));
207+ raise Not_found
208+ end ;
209+ ts', zs', t2, ps
210+ else
211+ [] , [] , t2, ps
212+ in
177213 let e1 = IL. VarE (" x" ) in
178214 let ts, zs, e =
179215 match norm_typ t1, freshen_typ env (norm_typ t2) with
@@ -335,7 +371,7 @@ let rec sub_typ infer_binds env t1 t2 ps =
335371 Trace. sub (lazy (" [sub_typ] done ts = " ^
336372 String. concat " , " (List. map string_of_norm_typ ts)));
337373 Trace. sub (lazy (" [sub_typ] done x -> " ^ IL. string_of_exp e));
338- ts, zs, IL. LamE (" x" , erase_typ t1, e)
374+ ts' @ ts, zs' @ zs, IL. LamE (" x" , erase_typ t1, e)
339375
340376and sub_extyp infer_binds env s1 s2 ps =
341377 Trace. sub (lazy (" [sub_extyp] s1 = " ^ string_of_norm_extyp s1));
@@ -394,5 +430,79 @@ and equal_row env tr1 tr2 ps =
394430 try sub_row false env tr2 tr1 ps with Sub e -> raise (Sub (Right e)) in
395431 zs1 @ zs2
396432
433+ and match_typ env t1 t2 ps =
434+ let t2 = norm_typ t2 in
435+ Trace. sub (lazy (" [match_typ] t1 = " ^ string_of_norm_typ t1));
436+ Trace. sub (lazy (" [match_typ] t2 = " ^ string_of_typ t2));
437+ Trace. sub (lazy (" [match_typ] ps = " ^
438+ String. concat " , " (List. map string_of_norm_typ ps)));
439+ if not (has_typs_typ ps t2) then [] , [] else
440+ match norm_typ t1, freshen_typ env t2 with
441+ | t1 , FunT (aks21 , t21 , ExT(aks22 , t22 ), Implicit) ->
442+ assert (aks22 = [] );
443+ let su, zs = match_typ (add_typs aks21 env) t1 t22 ps in
444+ List. map (fun (p , t ) -> (p, LamT (aks21, t))) su, lift env zs
445+
446+ | FunT (aks11 , t11 , ExT(aks12 , t12 ), Implicit), t2 ->
447+ assert (aks12 = [] );
448+ let ts1, zs1 = guess_typs (Env. domain_typ env) aks11 in
449+ let t1' = subst_typ (subst aks11 ts1) t12 in
450+ let su, zs2 = match_typ env t1' t2 ps in
451+ su, zs1 @ zs2
452+
453+ | TypT (s1 ), TypT (s2 ) ->
454+ (match s1, s2 with
455+ | ExT (aks1 , t ), ExT ([] , p ) when List. mem p ps ->
456+ if aks1 <> [] || not (! undecidable_flag || is_small_typ t) then
457+ raise (Sub (Mismatch (t1, t2)));
458+ [(p, t)], []
459+ | _ ->
460+ [] , [] )
461+
462+ | StrT (tr1 ), StrT (tr2 ) ->
463+ match_row env tr1 tr2 ps
464+
465+ | FunT (aks1 , t11 , s1 , Explicit p1 ), FunT (aks2 , t21 , s2 , Explicit p2 ) ->
466+ if p1 = Impure && p2 = Pure then raise (Sub (FunEffect (p1, p2)));
467+ if p1 <> Pure || p2 <> Pure then
468+ [] , []
469+ else
470+ let env' = add_typs aks2 env in
471+ let ts1, zs1, f1 =
472+ try sub_typ true env' t21 t11 (varTs aks1) with Sub e ->
473+ raise (Sub (FunParam e)) in
474+ let ps' = List. map (fun p -> AppT (p, varTs aks2)) ps in
475+ let su, zs2 =
476+ try match_extyp env' (subst_extyp (subst aks1 ts1) s1) s2 ps'
477+ with Sub e -> raise (Sub (FunResult e)) in
478+ List. map (function (AppT(p , _ ), t ) -> (p, LamT (aks2, t))
479+ | _ -> assert false ) su, lift env (zs1 @ zs2)
480+
481+ | _ ->
482+ [] , []
483+
484+ and match_extyp env s1 s2 ps =
485+ let ExT (aks2, t2) = freshen_extyp env s2 in
486+ let ExT (aks1, t1) = freshen_extyp (add_typs aks2 env) s1 in
487+ match aks1, aks2 with
488+ | [] , [] ->
489+ match_typ env t1 t2 ps
490+ | _ ->
491+ [] , []
492+
493+ and match_row env tr1 tr2 ps =
494+ match tr2 with
495+ | [] ->
496+ [] , []
497+ | (l , t2 )::tr2' ->
498+ let t1, zs, app = extract_bind true env tr1 l t2 in
499+ let su1, zs1 =
500+ try match_typ env t1 t2 ps with
501+ | Sub e -> raise (Sub (Struct (l, e))) in
502+ let su2, zs2 =
503+ match_row env tr1
504+ (subst_row (List. map (fun (p , t ) -> psubst p t) su1) tr2') ps in
505+ su1 @ su2, zs @ zs1 @ zs2
506+
397507let sub_typ = sub_typ true
398508let sub_extyp = sub_extyp true
0 commit comments