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
Stringup in anewtypeas @wowofbob suggests.However, sometimes this isn't feasible, in which case there are two general approaches to making something recognise
Stringspecifically.The first way, which is the natural Haskell approach, is to use a type class just like
Showto 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
Typeableclass, 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
Typeableis a very general class. You are delegating everything to the specific function you are calling; a function with aTypeableconstraint might have completely different implementations for lots of different concrete types.Finally, a further elaboration on the
Typeablesolution which gets closer to your original code is to use a couple of extensions:The use of
ViewPatternsallows us to write thecastinside a pattern, which may fit in more nicely with more complicated examples. In fact we can omit the:: Stringtype constraint because the body of this cases forcessto be the result type ofshow_, i.e.String, anyway. But that's a little obscure so I think it's better to be explicit.