synthExpr defs gam pol (Val s _ (Abs _ p Nothing e)) = do

  newConjunct

  tyVar <- freshTyVarInContext (mkId "t") KType
  let sig = (TyVar tyVar)

  (bindings, localVars, substP, elaboratedP, _) <- ctxtFromTypedPattern s sig p NotFull

  newConjunct

  pIrrefutable <- isIrrefutable s sig p
  if pIrrefutable then do
     (tau, gam'', subst, elaboratedE) <- synthExpr defs (bindings <> gam) pol e

     -- Locally we should have this property (as we are under a binder)
     ctxtApprox s (gam'' `intersectCtxts` bindings) bindings

     let finalTy = FunTy sig tau
     let elaborated = Val s finalTy (Abs finalTy elaboratedP (Just sig) elaboratedE)
     finalTy' <- substitute substP finalTy

     concludeImplication s localVars

     subst <- combineSubstitutions s substP subst

     return (finalTy', gam'' `subtractCtxt` bindings, subst, elaborated)
  else throw RefutablePatternError{ errLoc = s, errPat = p }
synthExpr defs gam pol (Val s _ (Abs _ p Nothing e)) = do

  newConjunct

  tyVar <- freshTyVarInContext (mkId "t") KType
  let sig = (TyVar tyVar)

  (bindings, localVars, substP, elaboratedP, _) <- ctxtFromTypedPattern s sig p NotFull

  newConjunct

  pIrrefutable <- isIrrefutable s sig p
  if pIrrefutable then do
     (tau, gam'', subst, elaboratedE) <- synthExpr defs (bindings <> gam) pol e

     -- Locally we should have this property (as we are under a binder)
     ctxtApprox s (gam'' `intersectCtxts` bindings) bindings

     let finalTy = FunTy sig tau
     let elaborated = Val s finalTy (Abs finalTy elaboratedP (Just sig) elaboratedE)
     finalTy' <- substitute substP finalTy

     concludeImplication s localVars

     subst <- combineSubstitutions s substP subst

     return (finalTy', gam'' `subtractCtxt` bindings, subst, elaborated)
  else throw RefutablePatternError{ errLoc = s, errPat = p }
synthExpr defs gam pol (Val s _ (Abs _ p Nothing e)) = do

  newConjunct

  tyVar <- freshTyVarInContext (mkId "t") KType
  let sig = (TyVar tyVar)

  (bindings, localVars, substP, elaboratedP, _) <- ctxtFromTypedPattern s sig p NotFull

  newConjunct

  pIrrefutable <- isIrrefutable s sig p
  if pIrrefutable then do
     (tau, gam'', subst, elaboratedE) <- synthExpr defs (bindings <> gam) pol e

     -- Locally we should have this property (as we are under a binder)
     ctxtApprox s (gam'' `intersectCtxts` bindings) bindings

     let finalTy = FunTy sig tau
     let elaborated = Val s finalTy (Abs finalTy elaboratedP (Just sig) elaboratedE)
     finalTy' <- substitute substP finalTy

     concludeImplication s localVars

     subst <- combineSubstitutions s substP subst

     return (finalTy', gam'' `subtractCtxt` bindings, subst, elaborated)
  else throw RefutablePatternError{ errLoc = s, errPat = p }