Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a polymorphic `toString` function that doesn't add quotes?

In most OO languages that I'm familiar with, the toString method of a String is actually just the identity function. But in Haskell show adds double quotes.

So if I write a function something like this

f :: Show a => [a] -> String
f = concat . map show

it works as expected for numbers

f [0,1,2,3]  -- "0123"

but Strings end up with extra quotes

f ["one", "two", "three"] -- "\"one\"\"two\"\"three\""

when I really want "onetwothree".

If I wanted to write f polymorphically, is there a way to do it with only a Show constraint, and without overriding the Show instance for String (if that's even possible).

The best I can come up with is to create my own type class:

class (Show a) => ToString a where
   toString = show

and add an instance for everything?

instance ToString String where toString = id
instance ToString Char where toString = pure
instance ToString Int
instance ToString Maybe
...etc
like image 916
Peter Hall Avatar asked Aug 27 '12 23:08

Peter Hall


2 Answers

I think the root cause of your problem is that show isn't really renderToText. It's supposed to produce text that you could paste into Haskell code to get the same value, or convert back to the same value using read.

For that purpose, show "foo" = "foo" wouldn't work, because show "1" = "1" and show 1 = "1", which loses information.

The operation you want to be able to apply to "foo" to get "foo" and to 1 to get "1" is something other than show. show just isn't a Java-esque toString.

When I've needed this before, I have indeed made my own new type class and made a bunch of things instances of it, and then used that rather than Show. Most of the instances were implemented with show, but String wasn't the only one I wanted to customise so the separate type class wasn't completely wasted. In practice, I found there were only a handful of types that I actually needed the instance for, and it was pretty trivial to add them as I got compile errors.

like image 167
Ben Avatar answered Nov 15 '22 12:11

Ben


The Pretty class and its corresponding type Doc have the needed behavior for Show. Your link shows a different use case, however; maybe you could edit the question?

like image 5
Mathnerd314 Avatar answered Nov 15 '22 11:11

Mathnerd314