anchor.diff:            else
               sprintf "%A%A" t tys
   
  +let (|App'|Var'|) ty =
  +  match ty with
  +   | Var v -> Var' v
  +   | App (tc, tys) -> App' (tc, tys)
  +   | Mono t ->
  +     if t.IsArray then
  +       App' (Arr (t.GetArrayRank ()), [|t.GetElementType () |> Mono|])
  +     elif t.IsGenericType then
  +       App' (Def (t.GetGenericTypeDefinition ()),
  +             t.GetGenericArguments () |> Array.map Mono)
  +     else
  +       App' (Def t, [||])
  +
  +[<CompilationRepresentation (CompilationRepresentationFlags.ModuleSuffix)>]
  +module TyCon =
  +  let apply tc ts =
  +    match (tc, ts) with
  +     | (Def t, ts) ->
  +       t.MakeGenericType ts
  +     | (Arr r, [|t|]) ->
  +       if r = 1
  +       then t.MakeArrayType ()
  +       else t.MakeArrayType r
  +     | _ ->
  +       failwith "Bug: apply %A %A" tc ts
  +
   module Ty =
  +  let inline containsVars ty =
  +    match ty with
  +     | Mono _ -> false
  +     | Var _ | App _ -> true
  +
     let rec ofType (t: Type) =
       if t.IsArray then
  -      App (Arr (t.GetArrayRank ()), [|ofType (t.GetElementType ())|])
  +      match t.GetElementType () |> ofType with
  +       | Mono _ ->
  +         Mono t
  +       | ty ->
  +         App (Arr (t.GetArrayRank ()), [|ty|])
       elif t.IsGenericParameter then
         Var t
       elif t.IsGenericType then
  -      App (Def (t.GetGenericTypeDefinition ()),
  -           t.GetGenericArguments () |> Array.map ofType)
  +      let tys = t.GetGenericArguments () |> Array.map ofType
  +      if Array.exists containsVars tys
  +      then App (Def (t.GetGenericTypeDefinition ()), tys)
  +      else Mono t
       else
  -      App (Def t, [||])
  -
  -  let toMonoType (tyOriginal: Ty<'any>) =
  -    let rec toMonoType ty : option<Type> =
  -      match ty with
  -       | Var _ ->
  -         None
  -       | App (Arr r, [|ty|]) ->
  -         toMonoType ty
  -         |> Option.map (fun t ->
  -            if r = 1
  -            then t.MakeArrayType ()
  -            else t.MakeArrayType r)
  -       | App (Arr _, _) -> failwithf "Bug: %A" ty
  -       | App (Def t, [||]) -> Some t
  -       | App (Def t, tys) ->
  -         tys
  -         |> Array.chooseAll toMonoType
  -         |> Option.map (fun tys -> t.MakeGenericType tys)
  -    toMonoType tyOriginal
  +      Mono t
  +
  +  let inline toMonoType (ty: Ty<'any>) =
  +    match ty with
  +     | Mono t -> Some t
  +     | Var _ | App _ -> None
   
   ////////////////////////////////////////////////////////////////////////////////
  -
  -  let rec containsVars ty =
  -    match ty with
  -     | Var _ -> true
  -     | App (_, tys) -> Array.exists containsVars tys
   
     let rec resolveTop v2ty ty =
       match ty with
  
positive.code: 
    let rec tryMatchIn formal actual v2ty =
      match (resolveTop v2ty formal, resolveTop v2ty actual) with
       | (Var fv, Var av) when fv = av ->
         Some v2ty
       | (Var v, ty) | (ty, Var v) when not (occurs v2ty v ty) ->
         Some (HashEqMap.add v ty v2ty)
       | (App (formal, pars), App (actual, args)) when formal = actual ->
         assert (pars.Length = args.Length)
         let rec loop i v2ty =
           if i < pars.Length then
  
negative.code:      | Many rs -> yield! rs
       | Branch (at, apps, vars) ->
         match getAt at actual with
          | None | Some (Var' _) ->
            yield! HashEqMap.toSeq apps
                   |> Seq.collect (fun (_, formal) ->
                      filter formal actual)
          | Some (App' (tc, _)) ->
            match HashEqMap.tryFind tc apps with
             | None -> ()
             | Some formal ->
  