14
votes

Why does the Haskell base package only define the IsString class to have a conversion from String to 'like-string' value, and not define the inverse transformation, from 'like-string' value to String?

The class should be defined as:

class IsString a where
    fromString :: String -> a
    toString :: a -> String

ref: http://hackage.haskell.org/packages/archive/base/4.4.0.0/doc/html/Data-String.html

2
I do not know Haskell, but you could likely create your own inverse. - Michael

2 Answers

16
votes

The reason is IMHO that IsString's primary purpose is to be used for string literals in Haskell source code (or (E)DSLs -- see also Paradise: A two-stage DSL embedded in Haskell) via the OverloadedStrings language extension in an analogous way to how other polymorphic literals work (e.g. via fromRational for floating point literals or fromInteger for integer literals)

The term IsString might be a bit misleading, as it suggests that the type-class represents string-like structures, whereas it's really just to denote types which have a quoted-string-representation in Haskell source code.

7
votes

If you desire to use toString :: a -> String, I think you're simply forgetting about show :: a -> String, or more properly Show a => show :: a -> String.

If you want to operate on a type both having a :: a -> String and :: String -> a, you can simply put those type-class constraints on the functions.

doubleConstraintedFunction :: Show a, IsString a => a -> .. -> .. -> a

We carefully note that we avoid defining type classes having a set of functions that can as well be split into two subclasses. Therefor we don't put toString in IsString.

Finally, I must also mention about Read, which provides Read a => String -> a. You use read and show for very simple serialization. fromString from IsString has a different purpose, it's useful with the language pragma OverloadedStrings, then you can very conveniently insert code like "This is not a string" :: Text. (Text is a (efficient) data-structure for Strings)