AFAIK tuples aren't defined anywhere, so to avoid orphan instances[1] the Show instances for tuples have to be defined in GHC.Show[2]. The implementation of those instances happens to use foldr1
:
show_tuple :: [ShowS] -> ShowS
show_tuple ss = showChar '('
. foldr1 (\s r -> s . showChar ',' . r) ss
. showChar ')'
so GHC.Show imports GHC.List where that function is defined. GHC.List, in turn, defines lookup
, which is in the Maybe
monad (good old Haskell 98's monomorphism bias I guess). So GHC.List imports Data.Maybe. In order to define a Show
instance, Data.Maybe would need to import GHC.Show (directly or indirectly), which would make the whole sequence GHC.Show -> GHC.List -> Data.Maybe -> GHC.Show a circular dependency. GHC doesn't support circular dependencies very well (not that they're easy to support!), so base works really hard to avoid them.
[1] An orphan instance is one defined in a different module than both the class and the type involved in the instance. Formally, Haskell requires instance search to be done in any module directly or indirectly imported by the module being compiled; but for non-orphan instances GHC can short-circuit that and just look in two places. For orphan instances, it has to track every orphan instance in a module and then track that those instances are re-exposed by every module that imports them, which is more expensive (and means it has to keep a context environment with potentially many instances that aren't even relevant to the current module, because it doesn't actually import those classes or types). So good practice is to avoid orphan instances for that reason.
Somewhat more philosophically, orphan instances are a really good way to get two conflicting instances of the same class / type in your program, which since they are both 'visible' in your Main
module means they will conflict. So the language feature itself is kind of dodgy.
[2] IIRC GHC only provides Show
instances up to a (relatively small) fixed number of tuple components, which isn't quite Haskell 98 compliant but is good enough for any practical programming need. (Seriously, don't use tuples with more than 3 elements anyway, you will forget what specific components mean). I don't know if the standard has been updated to bring GHC into compliance in the last few years or not.