Overlapping instance for Show - haskell

Suppose we have the following:
{-# LANGUAGE FlexibleInstances #-}
module Sample where
newtype A a =
A a
deriving (Show)
newtype L a =
L [a]
class ListContainer l where
getList :: l a -> [a]
instance ListContainer L where
getList (L l) = l
instance (Show a, ListContainer l) => Show (l a) where
show = const "example"
With this code, ghc complains:
warning: [-Wdeferred-type-errors]
• Overlapping instances for Show (A a)
    arising from a use of ‘GHC.Show.$dmshowList’
  Matching instances:
    instance (Show a, ListContainer l) => Show (l a)
      -- Defined at /.../src/Sample.hs:18:10
    instance Show a => Show (A a)
      -- Defined at /.../src/Sample.hs:7:13
• In the expression: GHC.Show.$dmshowList #(A a)
  In an equation for ‘showList’:
      showList = GHC.Show.$dmshowList #(A a)
  When typechecking the code for ‘showList’
    in a derived instance for ‘Show (A a)’:
    To see the code I am typechecking, use -ddump-deriv
  In the instance declaration for ‘Show (A a)’
warning: [-Wdeferred-type-errors]
• Overlapping instances for Show (A a)
    arising from a use of ‘GHC.Show.$dmshow’
  Matching instances:
    instance (Show a, ListContainer l) => Show (l a)
      -- Defined at /.../src/Sample.hs:18:10
    instance Show a => Show (A a)
      -- Defined at /.../src/Sample.hs:7:13
• In the expression: GHC.Show.$dmshow #(A a)
  In an equation for ‘show’: show = GHC.Show.$dmshow #(A a)
  When typechecking the code for ‘show’
    in a derived instance for ‘Show (A a)’:
    To see the code I am typechecking, use -ddump-deriv
  In the instance declaration for ‘Show (A a)’
I can understand that it thinks type a can either derive Show, or derive ListContainer, which may result in Show.
How do we avoid that?
I understand that there exists a function showList, but its signature is a bit foreign. I do already have a function that I intend to use to display certain lists, which returns String directly.

I can understand that it thinks type a can either derive Show, or derive ListContainer, which may result in Show.
That is not what it thinks.
When Haskell chooses class instance, it doesn't look at instance constraints at all. All it considers when choosing an instance is the instance head (the thing that comes right after class name).
In your Show instance, the instance head is l a. This instance head matches A a (by assuming l = A). It also matches a lot of other things by the way - for example, it matches Maybe a (where l = Maybe), and Either b a (with l = Either b), and Identity a, and IO a - pretty much every type with a type parameter, come to think of it. It doesn't matter that neither A nor Maybe nor IO have an instance of ListContainer, because like I said above, Haskell doesn't look at constraints when choosing instances, only at instance heads.
It is only after finding a matching instance (by matching on its head) that Haskell will check if that instance's constraints are in fact satisfied. And will complain if they aren't. But it will never go back and try to pick another instance instead.
So coming back to your example: since A now has two matching Show instances - its own derived one and the Show (l a) one that you wrote, - the compiler complains that they are overlapping.

In your example you can just remove instance (Show a, ListContainer l) => Show (l a) and add deriving (Show) to L definition.
Alternatively you can remove deriving (Show) from A definition.
If you want you code behave as it is now remove deriving (Show) and implement it explicitly
instance {-# OVERLAPPING #-} Show a => Show (A a)
where
show (A a) = "A " ++ show a

Related

Set specific properties for data in Haskell

Let us say I want to make a ADT as follows in Haskell:
data Properties = Property String [String]
deriving (Show,Eq)
I want to know if it is possible to give the second list a bounded and enumerated property? Basically the first element of the list will be the minBound and the last element will be the maxBound. I am trying,
data Properties a = Property String [a]
deriving (Show, Eq)
instance Bounded (Properties a) where
minBound a = head a
maxBound a = (head . reverse) a
But not having much luck.
Well no, you can't do quite what you're asking, but maybe you'll find inspiration in this other neat trick.
{-# language ScopedTypeVariables, FlexibleContexts, UndecidableInstances #-}
import Data.Reflection -- from the reflection package
import qualified Data.List.NonEmpty as NE
import Data.List.NonEmpty (NonEmpty (..))
import Data.Proxy
-- Just the plain string part
newtype Pstring p = P String deriving Eq
-- Those properties you're interested in. It will
-- only be possible to produce bounds if there's at
-- least one property, so NonEmpty makes more sense
-- than [].
type Props = NonEmpty String
-- This is just to make a Show instance that does
-- what you seem to want easier to write. It's not really
-- necessary.
data Properties = Property String [String] deriving Show
Now we get to the key part, where we use reflection to produce class instances that can depend on run-time values. Roughly speaking, you can think of
Reifies x t => ...
as being a class-level version of
\(x :: t) -> ...
Because it operates at the class level, you can use it to parametrize instances. Since Reifies x t binds a type variable x, rather than a term variable, you need to use reflect to actually get the value back. If you happen to have a value on hand whose type ends in p, then you can just apply reflect to that value. Otherwise, you can always magic up a Proxy :: Proxy p to do the job.
-- If some Props are "in the air" tied to the type p,
-- then we can show them along with the string.
instance Reifies p Props => Show (Pstring p) where
showsPrec k p#(P str) =
showsPrec k $ Property str (NE.toList $ reflect p)
-- If some Props are "in the air" tied to the type p,
-- then we can give Pstring p a Bounded instance.
instance Reifies p Props => Bounded (Pstring p) where
minBound = P $ NE.head (reflect (Proxy :: Proxy p))
maxBound = P $ NE.last (reflect (Proxy :: Proxy p))
Now we need to have a way to actually bind types that can be passed to the type-level lambdas. This is done using the reify function. So let's throw some Props into the air and then let the butterfly nets get them back.
main :: IO ()
main = reify ("Hi" :| ["how", "are", "you"]) $
\(_ :: Proxy p) -> do
print (minBound :: Pstring p)
print (maxBound :: Pstring p)
./dfeuer#squirrel:~/src> ./WeirdBounded
Property "Hi" ["Hi","how","are","you"]
Property "you" ["Hi","how","are","you"]
You can think of reify x $ \(p :: Proxy p) -> ... as binding a type p to the value x; you can then pass the type p where you like by constraining things to have types involving p.
If you're just doing a couple of things, all this machinery is way more than necessary. Where it gets nice is when you're performing lots of operations with values that have phantom types carrying extra information. In many cases, you can avoid most of the explicit applications of reflect and the explicit proxy handling, because type inference just takes care of it all for you. For a good example of this technique in action, see the hyperloglog package. Configuration information for the HyperLogLog data structure is carried in a type parameter; this guarantees, at compile time, that only similarly configured structures are merged with each other.

How to apply wildcard in constraint in Haskell?

It sounds trivial but I can't find out what I'm supposed to do.
The following is my type definition:
data CDeq q a = Shallow (q a)
| Deep{ hq ⦂ q a
, susp ⦂ CDeq q (q a)
, tq ⦂ q a }
and I want it to have an instance of Show.
Since GHC doesn't allow deriving here, I just tried to write one myself:
instance (Show a, Show ????) => Show (CDeq q a) where
....
but I got stuck.
I don't know how to represent that for all type v, (q v) can be shown in Haskell.
I can't simply do the following:
instance (Show a, Show (q a)) => Show (CDeq q a) where
....
since to show CDeq q (q a), Show (q (q a)) is required, then Show (q (q (q a))) is required, then on and on.
So I am wondering is there a syntax such that I can express the meaning I stated up there?
I once thought forall could be the solution to this, but it doesn't work:
instance (Show a, forall v. Show (q v)) => Show (CDeq q a)
There's a class Show1 in Prelude.Extras to represent "for all type v, (q v) can be shown".
class Show1 f where
showsPrec1 :: Show a => Int -> f a -> ShowS
default showsPrec1 :: (Show (f a), Show a) => Int -> f a -> ShowS
showsPrec1 = showsPrec
...
You can use this to write a show instance for CDeq q a.
instance (Show a, Show1 q) => Show (CDeq q a) where
....
Where you would use show or showsPrec on a q x you'll instead use show1 or showsPrec1.
If you use these, you should also provide instances for CDeq q.
instance (Show1 q) => Show1 (CDeq q) where
showsPrec1 = showsPrec
#Cirdec's already accepted answer is a great pragmatic answer for this use case. I wanted to write a bit about more general techniques (especially the Data.Constraint.Forall mentioned in a comment, since that almost works for this use case but doesn't quite, and there's another thing from constraints that does work), but I wanted to also try to explain a bit about why this isn't directly possible first and what Show1, Forall, and Lifting do to work around that (they're each different trade offs). So it got a little long, apologies.
By standard Haskell mechanisms you can't have such a "wildcard" constraint. The reason is that Show makes a constraint from a type, with potentially a different instance (with different method definitions) for each type you could apply it to.
When your code requires a Show (CDeq q a) instance and finds instance (Show a, Show ????) => Show (CDeq q a), that means it now also needs to find an instance for Show a and Show ????.
Show a is easy; either a has already been chosen as some concrete type like Int, and it can use the Show instance for that type (or error if there isn't one in scope). Or your code was in a function that was polymorphic in a; in that case there must have been a Show a constraint on the function you wrote, so the compiler will just rely on the caller having chosen some particular a and passed in the Show a instance definition.
But the wildcard constraint Show ???? is different. We're not talking about a concrete type here, so that path to resolution isn't going to work. And we're not even talking about a polymorphic constraint in the sense that there's a type variable the caller would choose (in that case we could punt the problem of choosing a single instance dictionary to the caller).
What you need is to be able to show q a, and q (q a), and q (q (q a), etc. But each of those could have its own instance! The types are gone at runtime, so the compiler can't even attempt to round up all of those instances (or require the caller to pass in an unbounded number of instances) and emit code that switches between which show it calls. It needs to emit code that only calls one version of show; either a specific one from a specific instance it's been able to choose, or one that is passed in by the caller to the function.
One way to workaround this is with an alternative type class like Show1. Here the "unit of overloading" is on the * -> * type constructor. It's impossible to make a Show1 instance for types like Int (they're not the right shape), but a single Show1 q instance is applicable to all types of the form q a, so you don't need an unbounded number of instances to support q a, q (q a), q (q (q a)), etc anymore.
But there also are Show instances that are polymorphic in some type variables. For example the list instance is Show a => Show [a]; knowing that this instance exists (and there aren't any overlapping instances), we know we'll be using the same instance for [a], [[a]], [[[a]]], etc. If we could somehow write a constraint that required a polymorphic instance like that.
There's no direct way to say we want a polymorphic instance - the constraint language only allows us to ask for instances for particular types, or particular types that the caller chooses. But the Data.Forall module in the constraints package (https://hackage.haskell.org/package/constraints), which #Cirdec suggested in a comment, uses clever tricks internally to provide a few ways of doing this.1 Here's an example of how that would look:
{-# LANGUAGE FlexibleContexts
, ScopedTypeVariables
, TypeApplications
, TypeOperators
#-}
module Foo where
import Data.Constraint ( (:-), (\\) )
import Data.Constraint.Forall (ForallF, instF)
data Nested q a = Stop | Deeper a (Nested q (q a))
data None a = None
instance Show (None a)
where show None = "None"
instance (Show a, ForallF Show q) => Show (Nested q a)
where show Stop = "Stop"
show (Deeper a r) = show a ++ " " ++ show r
\\ (instF #Show #q #a)
The constraint ForallF Show q represents forall a. Show (q a).2 But it's not that constraint directly, so we can't just derive Show using this; we need to write an instance manually so we can do some massaging.
A ForallF constraint gives us access to instF which is of type forall p f a. ForallF p f :- p (f a). The :- is a type of the constraints package; values of type c :- d represent a proof that when the constraint c holds the constraint d also holds (or in terms of instance dictionaries: it contains a dictionary for d that's parameterised on a dictionary for c). So ForallF p f :- p (f a) is a proof that when we have ForallF p f we can get p (f a). Type application syntax is a less verbose way of pinning down the types at which we're using instF, we want the left side of :- to tie back to the ForallF Show q that we know we have from the instance constraint. That means the right hand side will give us a Show (q a), as we needed! The \\ operator just takes an expression on the left and an c :- d on the right, and basically connects c and d instances for us; the expression will be evaluated with access to a dictionary for d, but the overall expression only needs c.
Here's an example of use:
λ Deeper 'a' (Deeper None (Deeper None Stop))
'a' None None Stop
it :: Nested None Char
Hurrah! But why did I use None? What happens when we try it with nested lists?
λ :t Deeper [] (Deeper [] Stop)
Deeper [] (Deeper [] Stop) :: Nested [] [t]
λ Deeper [] (Deeper [] Stop)
<interactive>:65:1: error:
• No instance for (Show
(Data.Constraint.Forall.Skolem
(Data.Constraint.Forall.ComposeC Show [])))
arising from a use of ‘print’
• In a stmt of an interactive GHCi command: print it
Drat. What went wrong? Well, our polymorphic Show instance for lists is actually Show a => Show [a]. The instance head is polymorphic, so it applies to all types of forms [a]. But it also needs the extra constraint that Show a holds, so it's not truly polymorphic. Basically what happens is the internal unexported thing in Data.Constraint doesn't have an instance for Show (it can't have any instances for the technique to work), so we get the error above. And that's actually a good thing; dictionaries for [a] contain a nested dictionary for a, so the trick of getting an instance we know is polymorphic and then unsafeCoercing it to the right type wouldn't be applicable here. ForallF only works to find instances that are completely polymorphic, with no restrictions at all.
But there is one more thing the constraints package has to offer here! Data.Constraint.Lifting gives us a class Lifting p f, that represents the idea "p (f a) holds whenever p a holds". The idea that the constraint p "lifts through" the type constructor f. This is actually exactly the notion you needed, since you can just apply it recursively to nest arbitrarily many depths of q.
{-# LANGUAGE FlexibleContexts
, ScopedTypeVariables
, TypeApplications
, TypeOperators
#-}
module Foo where
import Data.Constraint ( (:-), (\\) )
import Data.Constraint.Lifting ( Lifting (lifting) )
data Nested q a = Stop | Deeper a (Nested q (q a))
instance (Show a, Lifting Show q) => Show (Nested q a)
where show Stop = "Stop"
show (Deeper a r) = show a ++ " " ++ show r
\\ (lifting #Show #q #a)
Here the lifting method of the class Lifting is doing basically what instF was doing before. lifting :: Lifting p f => p a :- p (f a), so when we have Lifting Show q and we have Show a, then we can use \\ and lifting (used at the right type) to get the Show (q a) dictionary we need to recursively invoke show.
Now we can show Nested applied to list types:
λ Deeper [] (Deeper [[True]] Stop)
[] [[True]] Stop
it :: Nested [] [Bool]
Data.Constraint.Lifting does have a lot of predefined instances for things in the prelude, but you'll likely to have to write your own instances. Fortunately this pretty much is generally a matter of writing:
instance Lifting SomeClass MyType
where lifting = Sub Dict
The instance resolver does all the actual work for you, provided your type really does allow that class to be "lifted through" it.
1 My understanding of the code in that module is not 100% complete (and the full details are a bit involved to make it as safe as possible), but basically the technique is to apply a class to a hidden unexported thing and capture the dictionary. Since no third-party instance could have actually referenced our unexported thing, the only way an instance could be resolved is if it was actually polymorphic and would work for anything. So then the captured dictionary can just be unsafeCoerced to apply to any type you like.
2 There are a few other variants of Forall* for representing different "shapes" of polymorphism in the constraint. I believe you can't make a one-size-fits-all version because you have to not mention the variable you're being polymorphic over, which means you can't actually use the constraint applied, you have to have something that takes the class as a parameter as well as all of the non-polymorphic parameters and applies them together in a particular fashion.

Showing the type A -> A

data A = Num Int
| Fun (A -> A) String deriving Show
instance Show (Fun (A -> A) String) where
show (Fun f s) = s
I would like to have an attribute for a function A -> A to print it, therefore there is a String type parameter to Fun. When I load this into ghci, I get
/home/kmels/tmp/show-abs.hs:4:16:
Not in scope: type constructor or class `Fun'
I guess this could be achieved by adding a new data type
data FunWithAttribute = FA (A -> A) String
adding data A = Num Int | Fun FunWithAttribute and writing an instance Show FunWithAttribute. Is the additional data type avoidable?
Instances are defined for types as a whole, not individual constructors, which is why it complains about Fun not being a type.
I assume your overall goal is to have a Show instance for A, which can't be derived because functions can't (in general) have a Show instance. You have a couple options here:
Write your own Show instance outright:
That is, something like:
instance Show A where
show (Num n) = "Num " ++ show n
show (Fun _ s) = s
In many cases, this makes the most sense. But sometimes it's nicer to derive Show, especially on complex recursive types where only one case of many is not automatically Show-able.
Make A derivable:
You can only derive Show for types that contain types that themselves have Show instances. There's no instance for A -> A, so deriving doesn't work. But you can write one that uses a placeholder of some sort:
instance Show (A -> A) where
show _ = "(A -> A)"
Or even just an empty string, if you prefer.
Note that this requires the FlexibleInstances language extension; it's one of the most harmless and commonly used extensions, is supported by multiple Haskell implementations, and the restrictions it relaxes are (in my opinion) a bit silly to begin with, so there's little reason to avoid it.
An alternate approach would be to have a wrapper type, as you mention in the question. You could even make this more generic:
data ShowAs a = ShowAs a String
instance Show (ShowAs a) where
show (ShowAs _ s) = s
...and then use (ShowAs (A -> A)) in the Fun constructor. This makes it a bit awkward by forcing you to do extra pattern matching any time you want to use the wrapped type, but it gives you lots of flexibility to "tag" stuff with how it should be displayed, e.g. showId = id `ShowAs` "id" or suchlike.
Perhaps I'm not following what you are asking for. But the above code could be written like this in order to compile:
data A = Num Int
| Fun (A -> A) String
instance Show A where
show (Fun f s) = s
show (Num i) = show i
Some explanation
It looked like you were trying to write a show instance for a constructor (Fun). Class instances are written for the entire data type (there might be exceptions, dunno). So you need to write one show matching on each constructor as part of the instance. Num and Fun are each constructors of the data type A.
Also, deriving can't be used unless each parameter of each constructor is, in turn, member of, in this case, Show. Now, your example is a bit special since it wants to Show (A -> A). How to show a function is somewhat explained in the other responses, although I don't think there is an exhaustive way. The other examples really just "show" the type or some place holder.
A Show instance (or any class instance) needs to be defined for a data type, not for a type constructor. That is, you need simply
instance Show A where
Apparently, you're trying to get this instance with the deriving, but that doesn't work because Haskell doesn't know how to show A->A. Now it seems you don't even want to show that function, but deriving Show instances always show all available information, so you can't use that.
The obvious, and best, solution to your problem is worldsayshi's: don't use deriving at all, but define a proper instance yourself. Alternatively, you can define a pseudo-instance for A->A and then use deriving:
{-# LANGUAGE FlexibleInstances #-}
data A = Num Int | Fun (A->A) String deriving(Show)
instance Show (A->A) where show _ = ""
This works like
Prelude> Fun (const $ Num 3) "bla"
Fun "bla"

Defining an algebra module using constructive-algebra package

The package constructive-algebra allows you to define instances of algebraic modules (like vectorial spaces but using a ring where a field was required)
This is my try at defining a module:
{-# LANGUAGE MultiParamTypeClasses, TypeSynonymInstances #-}
module A where
import Algebra.Structures.Module
import Algebra.Structures.CommutativeRing
import Algebra.Structures.Group
newtype A = A [(Integer,String)]
instance Group A where
(A a) <+> (A b) = A $ a ++ b
zero = A []
neg (A a) = A $ [((-k),c) | (k,c) <- a]
instance Module Integer A where
r *> (A as) = A [(r <*> k,c) | (k,c) <- as]
It fails by:
A.hs:15:10:
Overlapping instances for Group A
arising from the superclasses of an instance declaration
Matching instances:
instance Ring a => Group a -- Defined in Algebra.Structures.Group
instance Group A -- Defined at A.hs:9:10-16
In the instance declaration for `Module Integer A'
A.hs:15:10:
No instance for (Ring A)
arising from the superclasses of an instance declaration
Possible fix: add an instance declaration for (Ring A)
In the instance declaration for `Module Integer A'
Failed, modules loaded: none.
If I comment the Group instance out, then:
A.hs:16:10:
No instance for (Ring A)
arising from the superclasses of an instance declaration
Possible fix: add an instance declaration for (Ring A)
In the instance declaration for `Module Integer A'
Failed, modules loaded: none.
I read this as requiring an instance of Ring A to have Module Integer A which doesn't make sense and is not required in the class definition:
class (CommutativeRing r, AbelianGroup m) => Module r m where
-- | Scalar multiplication.
(*>) :: r -> m -> m
Could you explain this?
The package contains an
instance Ring a => Group a where ...
The instance head a matches every type expression, so any instance with any other type expression will overlap. That overlap only causes an error if such an instance is actually used somewhere. In your module, you use the instance in
instance Module Integer A where
r *> (A as) = A [(r <*> k,c) | (k,c) <- as]
The Module class has an AbelianGroup constraint on the m parameter¹. That implies a Group constraint. So for this instance, the Group instance of A must be looked up. The compiler finds two matching instances.
That is the first reported error.
The next is because the compiler tries to find an AbelianGroup instance for A. The only instance the compiler knows about at that point is
instance (Group a, Ring a) => AbelianGroup a
so it tries to find the instance Ring A where ..., but of course there isn't one.
Instead of commenting out the instance Group A where ..., you should add an
instance AbelianGroup a
(even if it's a lie, we just want to make it compile at the moment) and also add OverlappingInstances to the
{-# LANGUAGE #-} pragma.
With OverlappingInstances, the most specific matching instance is chosen, so it does what you want here.
¹ By the way, your A isn't an instance of AbelianGroup and rightfully can't be unless order is irrelevant in the [(Integer,String)] list.
This type checks without obnoxious language extensions.
{-# LANGUAGE MultiParamTypeClasses, TypeSynonymInstances #-}
module A where
import Algebra.Structures.Module
import Algebra.Structures.CommutativeRing
import Algebra.Structures.Group
newtype A = A [(Integer,String)]
instance Ring A where
A xs <+> A ys = A (xs ++ ys)
neg (A a) = A $ [((-k),c) | (k,c) <- a]
A x <*> A y = A [b | a <- x, b <- y ]
one = A []
zero = A []
instance Module Integer A where
r *> (A as) = A [(r <*> k,c) | (k,c) <- as]
It is a little confusing that <+> <*> and neg are defined independently in Ring and Group; they are completely separate symbols, but then they are brought together in the general instance that makes all Rings Groups, so if Ring is defined, Group mustn't be defined, since it's already spoken for. I'm not sure this is forced on the author by the way the type class system works. Module requires Ring or rather CommutativeRing. CommutativeRing is just basically renaming Ring; nothing further is to be defined. It is supposed to commit you to what is in Haskell an uncheckable assertion of commutativity. So you are supposed to "prove the CommutativeRing laws", so to speak, outside the module before making the Module instance. Note however that these laws are expressed in quickcheck propositions, so you are supposed to run quickcheck on propMulComm and propCommutativeRing specialized to this type.
Don't know what to do about one and zero, but you can get past the point about order by using a suitable structure, maybe:
import qualified Data.Set as S
newtype B = B {getBs :: S.Set (Integer,String) }
But having newtyped you can also, e.g., redefine Eq on A's to make sense of it, I suppose. In fact you have to to run the quickcheck propositions.
Edit: Here is a version with added material needed for QuickCheck http://hpaste.org/68351 together with "Failed" and "OK" quickcheck-statements for different Eq instances. This package is seeming pretty reasonable to me; I think you should redefine Module if you don't want the Ring and CommutativeRing business, since he says he "Consider[s] only the commutative case, it would be possible to implement left and right modules instead." Otherwise you won't be able to use quickcheck, which is clearly the principal point of the package, now that I see what's up, and which he has made it incredibly easy to do. As it is A is exactly the kind of thing he is trying to rule out with the all-pervasive use of quickcheck, which it would surely be very hard to trick in this sort of case.

Haskell Existential Types

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

Resources