[Haskell-cafe] How to support multiple string types in Haskell?

Tobias Dammers tdammers at gmail.com
Thu Jul 14 07:24:29 UTC 2016

In my experience, it is usually a more pragmatic solution to pick the
string type that is most suitable for the library's purposes, and leave
conversions to the consumer.

In practice, the choice is typically between strict and lazy Text only:
bytestrings do not represent strings but byte arrays, so they are not
suitable for textual data; and String has atrocious performance, unless the
use case is just linear character-wise traversal (and even then, lazy Texts
are probably still a better choice). I would only choose String if my
library were closely related to another library that has already picked
String, and converting to and from Text would introduce a lot of overhead.

The downside of making your API polymorphic is that you will often find
yourself having to type-annotate to disambiguate (foo . (bar :: Int ->
Text) $ n), or introduce type-binding dummy functions (foo . asText . bar $
n). Another downside is that there is no canonical "StringLike" typeclass,
so you either have to write your own, or pick one as a dependency. That
said, there are a few libraries out there that aim to make the Haskell
string situation less painful, including my own string-convert. They all
differ in a few details, it mostly comes down to preference.
On Jul 14, 2016 3:00 AM, "Edward Z. Yang" <ezyang at mit.edu> wrote:

> Hello KwangYul,
> Supporting this sort of parametricity is one of the goals of the
> Backpack project.  You can see some code that demonstrates
> how this might be done:
> https://github.com/yihuang/tagstream-conduit/pull/18
> Maybe you'll get to use this feature in GHC 8.2!
> A big problem with StringLike type classes is that you must
> pre-commit to the set of operations which are supported before
> hand. For strings, there are many, many such operations, and it is
> difficult to agree a priori what these operations should be.
> Edward
> Excerpts from KwangYul Seo's message of 2016-07-13 17:40:13 -0700:
> > Hi all,
> >
> > There are multiple string types in Haskell – String, lazy/strict
> > ByteString, lazy/strict Text to name a few. So to make a string handling
> > function maximally reusable, it needs to support multiple string types.
> >
> > One approach used by TagSoup library is to make a type class StringLike
> > which represents the polymorphic string type and uses it where a String
> > type is normally needed. For example,
> >
> > parseTags :: StringLike str => str -> [Tag str]
> >
> > Here parseTags takes a StringLike type instead of a fixed string type.
> > Users of TagSoup can pick any of String, lazy/strict ByteString,
> > lazy/strict Text because they are all instances of StringLike type class.
> >
> > It seems StringLike type class is quite generic but it is used only in
> the
> > TagSoup package. This makes me wonder what is the idiomatic way to
> support
> > multiple string types in Haskell. What other approaches do we have?
> >
> > Thanks,
> > Kwang Yul Seo
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20160714/eca2e244/attachment-0001.html>

More information about the Haskell-Cafe mailing list