I'm trying to wrap my brain around Haskell's existential types, and my first example is a heterogeneous list of things that can be shown:
{-# LANGUAGE ExistentialQuantification #-}
data Showable = forall a. Show a => Showable a
showableList :: [Showable]
showableList = [Showable "frodo", Showable 1]
Now it seems to me that the next thing I would want to do is make Showable an instance of Show so that, for example, my showableList could be displayed in the repl:
instance Show Showable where
show a = ...
The problem I am having is that what I really want to do here is call the a's underlying show implementation. But I'm having trouble referring to it:
instance Show Showable where
show a = show a
picks out Showable's show method on the RHS which runs in circles. I tried auto-deriving Show, but that doesn't work:
data Showable = forall a. Show a => Showable a
deriving Show
gives me:
Can't make a derived instance of `Show Showable':
Constructor `Showable' does not have a Haskell-98 type
Possible fix: use a standalone deriving declaration instead
In the data type declaration for `Showable'
I'm looking for someway to call the underlying Show::show implementation so that Showable does not have to reinvent the wheel.
instance Show Showable where
show (Showable a) = show a
show a = show a
doesn't work as you realized because it recurses infinitely. If we try this without existential types we can see the same problem and solution
data D = D Int
instance Show D where show a = show a -- obviously not going to work
instance Show D where show (D a) = "D " ++ (show a) -- we have to pull out the underlying value to work with it