I tried to write a variation on show
that treats strings differently from other instances of Show
, by not including the " and returning the string directly. But I don't know how to do it. Pattern matching? Guards? I couldn't find anything about that in any documentation.
Here is what I tried, which doesn't compile:
show_ :: Show a => a -> String
show_ (x :: String) = x
show_ x = show x
If possible, you should wrap your values of type
String
up in anewtype
as @wowofbob suggests.However, sometimes this isn't feasible, in which case there are two general approaches to making something recognise
String
specifically.The first way, which is the natural Haskell approach, is to use a type class just like
Show
to get different behaviour for different types. So you might writeand then
and so on for any other type you want to use. This has the disadvantage that you need to explicitly write out
Show_
instances for all the types you want.@AndrewC shows how you can cut each instance down to a single line, but you'll still have to list them all explicitly. You can in theory work around this, as detailed in this question, but it's not pleasant.
The second option is to get true runtime type information with the
Typeable
class, which is quite short and simple in this particular situation:This is not a natural Haskell-ish approach because it means callers can't tell much about what the function will do from the type.
Type classes in general give constrained polymorphism in the sense that the only variations in behaviour of a particular function must come from the variations in the relevant type class instances. The
Show_
class gives some indication what it's about from its name, and it might be documented.However
Typeable
is a very general class. You are delegating everything to the specific function you are calling; a function with aTypeable
constraint might have completely different implementations for lots of different concrete types.Finally, a further elaboration on the
Typeable
solution which gets closer to your original code is to use a couple of extensions:The use of
ViewPatterns
allows us to write thecast
inside a pattern, which may fit in more nicely with more complicated examples. In fact we can omit the:: String
type constraint because the body of this cases forcess
to be the result type ofshow_
, i.e.String
, anyway. But that's a little obscure so I think it's better to be explicit.