I’m trying to construct a datatype that is essentially a binary tree whose: each node’s left branch is a function that can act on the variable in each node’s right branch. I’m new to Haskell, and I’m not sure I’m going about this the right way, but my current problem is that I can’t figure out how to add my type to the Show typeclass. Here is my attempt:
{-# LANGUAGE ExistentialQuantification #-}
-- file: TS.hs
data TypeSentence a = forall b. Apply (TypeSentence (b->a)) (TypeSentence b)
| Expr a
instance (Show a) => (Show (TypeSentence a)) where
show (Expr x) = show x
show (Apply x y) = (show x) ++ " " ++ (show y)
instance (Show (TypeSentence b->a)) where
show (Expr x) = show "hello"
x = Expr 1
f = Expr (+1)
s = Apply f x
However, when I load this into ghci I get the following error:
TS.hs:9:24:
Could not deduce (Show (b -> a)) from the context ()
arising from a use of `show' at TS.hs:9:24-29
Possible fix:
add (Show (b -> a)) to the context of the constructor `Apply'
or add an instance declaration for (Show (b -> a))
In the first argument of `(++)', namely `(show x)'
In the expression: (show x) ++ " " ++ (show y)
In the definition of `show':
show (Apply x y) = (show x) ++ " " ++ (show y)
Failed, modules loaded: none.
Any ideas how I go about adding the Show (b->a) declaration?
Thanks.
There are a few problems with your code as written, so I’m going to go through them one by one.
You can’t add a particularly informative instance for
Show (a -> b). Consider how you’d have to write it:Since
fis a function, there’s nothing you can do with it other than apply it to a value; and sinceais a fully-polymorphic type, you can’t create a value of typeato applyfto. So your only option is something likeAs Daniel Fischer said in a comment, this is available in the Text.Show.Functions module. I wouldn’t actually bother with this, though; I’d just write something like
Since
showcan only return the one string for any function, just inline that directly.Even then, though, you still can’t write that
Showinstance. If you try to compile the instance above, you get the following error:The problem is that, in your definition of
TypeSentence,Applyhides a variable (bound asxin the definition ofshow) ofTypeSentenceparametrized by some arbitrary existentially-hidden typeb. But there’s no guarantee thatbis showable, soshow xwon’t type check, which is the error produced above: there’s no instance forShow b, becausebis arbitrary. So to get rid of that, the simplest approach would beAnd that’s not particularly useful. So maybe there’s not a good
Showinstance forTypeSentence. (And that’s fine. Many useful types don’t haveShowinstances.)This one’s unrelated to everything else. The
instance Show (TypeSentence b -> a)declaration tries to declare an instance ofShowfor functions fromTypeSentence btoa; if you reparenthesize that asinstance Show (TypeSentence (b -> a)), you still need both theFlexibleInstancesandOverlappingInstancesextension to get that to compile. So that you should probably just axe.