`[source] `_ compiler/typecheck/TcClassDcl.hs ================================ Note [Polymorphic methods] ~~~~~~~~~~~~~~~~~~~~~~~~~~ `[note link] `__ Consider class Foo a where op :: forall b. Ord b => a -> b -> b -> b instance Foo c => Foo [c] where op = e When typechecking the binding 'op = e', we'll have a meth_id for op whose type is op :: forall c. Foo c => forall b. Ord b => [c] -> b -> b -> b So tcPolyBinds must be capable of dealing with nested polytypes; and so it is. See TcBinds.tcMonoBinds (with type-sig case). Note [Silly default-method bind] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ `[note link] `__ When we pass the default method binding to the type checker, it must look like op2 = e not $dmop2 = e otherwise the "$dm" stuff comes out error messages. But we want the "$dm" to come out in the interface file. So we typecheck the former, and wrap it in a let, thus $dmop2 = let op2 = e in op2 This makes the error messages right.