We have instance IsString [Char]
and instance IsList (NonEmpty a)
.
Let’s also have IsString (NonEmpty Char)
.
IsString
is a class that is used with the -XOverloadedStrings
extension to support string literals of types other than String
- for instance, with the IsString Text
instance in scope, you can write "foobar" :: Text
and it will compile.
For reference, the
standard libraries supply the following instances of IsString
:
instance (a ~ Char) => IsString [a]
instance IsString a => IsString (Const a b)
instance IsString a => IsString (Identity a)
I propose adding a new
instance of IsString
for NonEmpty
lists of characters. NonEmpty
has been in base
starting from version 4.9, and for that reason people are
starting to use it more often - e.g. the popular megaparsec
library defines its custom error type like this:
data ErrorItem t
= Tokens (NonEmpty t) -- ^ Non-empty stream of tokens
| Label (NonEmpty Char) -- ^ Label (cannot be empty)
| EndOfInput -- ^ End of input
Here NonEmpty Char
stands for “non-empty string”. Without the IsString
instance users are forced to write non-empty strings in an
inconvenient and awkward-looking way (e.g. Label ('f' :| "oobar")
);
the instance makes Label "foobar"
an acceptable notation, thus making the NonEmpty Char
type more viable for use in libraries and user-facing APIs.
Here’s a sample implementation:
instance (a ~ Char) => IsString (NonEmpty a) where
fromString (a:as) = a :| as
fromString "" = errorWithoutStackTrace "NonEmpty.fromString: empty string"
This mirrors the IsList
instance for NonEmpty
.
(The reason I haven’t used fromList
is that I want the error message to say “fromString” instead of
“fromList”.)
If this is accepted, I can make a patch.