メモ
http://www.haskell.org/ghc/docs/7.0.1/html/libraries/ghc-7.0.1/src/TcInstDcls.html
Note [Single-method classes] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If the class has just one method (or, more accurately, just one element of {superclasses + methods}), then we still use the *same* strategy class C a where op :: a -> a instance C a => C [a] where op = <blah> We translate the class decl into a newtype, which just gives a top-level axiom: axiom Co:C a :: C a ~ (a->a) op :: forall a. C a -> (a -> a) op a d = d |> (Co:C a) MkC :: forall a. (a->a) -> C a MkC = /\a.\op. op |> (sym Co:C a) df :: forall a. C a => C [a] {-# NOINLINE df DFun[ $cop_list ] #-} df = /\a. \d. MkC ($cop_list a d) $cop_list :: forall a. C a => [a] -> [a] $cop_list = <blah> The "constructor" MkC expands to a cast, as does the class-op selector. The RULE works just like for multi-field dictionaries: * (df a d) returns (Just (MkC,..,[$cop_list a d])) to exprIsConApp_Maybe * The RULE for op picks the right result This is a bit of a hack, because (df a d) isn't *really* a constructor application. But it works just fine in this case, exprIsConApp_maybe is otherwise used only when we hit a case expression which will have a real data constructor in it. The biggest reason for doing it this way, apart from uniformity, is that we want to be very careful when we have instance C a => C [a] where {-# INLINE op #-} op = ... then we'll get an INLINE pragma on $cop_list but it's important that $cop_list only inlines when it's applied to *two* arguments (the dictionary and the list argument The danger is that we'll get something like op_list :: C a => [a] -> [a] op_list = /\a.\d. $cop_list a d and then we'll eta expand, and then we'll inline TOO EARLY. This happened in Trac #3772 and I spent far too long fiddling around trying to fix it. Look at the test for Trac #3772. (Note: re-reading the above, I can't see how using the uniform story solves the problem.)