+Implicit Parameter bindings.
+
+\begin{code}
+tcMonoExpr (HsWith expr binds) res_ty
+ = tcMonoExpr expr res_ty `thenTc` \ (expr', lie) ->
+ tcIPBinds binds `thenTc` \ (binds', types, lie2) ->
+ partitionPredsOfLIE isBound lie `thenTc` \ (ips, lie', dict_binds) ->
+ let expr'' = if nullMonoBinds dict_binds
+ then expr'
+ else HsLet (mkMonoBind (revBinds dict_binds) [] NonRecursive)
+ expr'
+ in
+ tcCheckIPBinds binds' types ips `thenTc_`
+ returnTc (HsWith expr'' binds', lie' `plusLIE` lie2)
+ where isBound p
+ = case ipName_maybe p of
+ Just n -> n `elem` names
+ Nothing -> False
+ names = map fst binds
+ -- revBinds is used because tcSimplify outputs the bindings
+ -- out-of-order. it's not a problem elsewhere because these
+ -- bindings are normally used in a recursive let
+ -- ZZ probably need to find a better solution
+ revBinds (b1 `AndMonoBinds` b2) =
+ (revBinds b2) `AndMonoBinds` (revBinds b1)
+ revBinds b = b
+
+tcIPBinds ((name, expr) : binds)
+ = newTyVarTy openTypeKind `thenTc` \ ty ->
+ tcGetSrcLoc `thenTc` \ loc ->
+ let id = ipToId name ty loc in
+ tcMonoExpr expr ty `thenTc` \ (expr', lie) ->
+ zonkTcType ty `thenTc` \ ty' ->
+ tcIPBinds binds `thenTc` \ (binds', types, lie2) ->
+ returnTc ((id, expr') : binds', ty : types, lie `plusLIE` lie2)
+tcIPBinds [] = returnTc ([], [], emptyLIE)
+
+tcCheckIPBinds binds types ips
+ = foldrTc tcCheckIPBind (getIPsOfLIE ips) (zip binds types)
+
+-- ZZ how do we use the loc?
+tcCheckIPBind bt@((v, _), t1) ((n, t2) : ips) | getName v == n
+ = unifyTauTy t1 t2 `thenTc_`
+ tcCheckIPBind bt ips `thenTc` \ ips' ->
+ returnTc ips'
+tcCheckIPBind bt (ip : ips)
+ = tcCheckIPBind bt ips `thenTc` \ ips' ->
+ returnTc (ip : ips')
+tcCheckIPBind bt []
+ = returnTc []
+\end{code}
+