<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <div class="markdown-here-wrapper" data-md-url="Thunderbird"
      style="">
      <h3 id="tl-dr" style="margin: 1.3em 0px 1em; padding: 0px;
        font-weight: bold;font-size: 1.3em;">tl;dr</h3>
      <p style="margin: 1.2em 0px ! important;">We have <code style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">instance IsString [Char]</code>
        and <code style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">instance IsList (NonEmpty a)</code>.
        Let’s also have <code style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">IsString (NonEmpty Char)</code>.</p>
      <h3 id="background" style="margin: 1.3em 0px 1em; padding: 0px;
        font-weight: bold;font-size: 1.3em;">Background</h3>
      <p style="margin: 1.2em 0px ! important;"><code style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">IsString</code>
        is a class that is used with the <code style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">-XOverloadedStrings</code>
        extension to support string literals of types other than <code style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">String</code>
        - for instance, with the <code style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">IsString Text</code>
        instance in scope, you can write <code style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">"foobar" :: Text</code>
        and it will compile.</p>
      <p style="margin: 1.2em 0px ! important;">For reference, the
        standard libraries supply the following instances of <code style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">IsString</code>:</p>
      <pre style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code class="hljs language-haskell" style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block ! important;display: block; padding: 0.5em; color: rgb(51, 51, 51); background: rgb(248, 248, 255) none repeat scroll 0% 0%;"><span class="hljs-class"><span class="hljs-keyword">instance</span> <span class="hljs-container">(<span class="hljs-title">a</span> ~ <span class="hljs-type">Char</span>)</span> => <span class="hljs-type">IsString</span> [a]
<span class="hljs-keyword">instance</span> <span class="hljs-type">IsString</span> a => <span class="hljs-type">IsString</span> <span class="hljs-container">(<span class="hljs-type">Const</span> <span class="hljs-title">a</span> <span class="hljs-title">b</span>)</span>
<span class="hljs-keyword">instance</span> <span class="hljs-type">IsString</span> a => <span class="hljs-type">IsString</span> <span class="hljs-container">(<span class="hljs-type">Identity</span> <span class="hljs-title">a</span>)</span></span>
</code></pre>
      <h3 id="proposal" style="margin: 1.3em 0px 1em; padding: 0px;
        font-weight: bold;font-size: 1.3em;">Proposal</h3>
      <p style="margin: 1.2em 0px ! important;">I propose adding a new
        instance of <code style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">IsString</code>
        for <code style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">NonEmpty</code>
        lists of characters. <code style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">NonEmpty</code>
        has been in <code style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">base</code>
        starting from version 4.9, and for that reason people are
        starting to use it more often - e.g. the popular <code style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">megaparsec</code>
        library defines its custom error type like this:</p>
      <pre style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code class="hljs language-haskell" style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block ! important;display: block; padding: 0.5em; color: rgb(51, 51, 51); background: rgb(248, 248, 255) none repeat scroll 0% 0%;"><span class="hljs-typedef"><span class="hljs-keyword">data</span> <span class="hljs-type">ErrorItem</span> t</span>
  = <span class="hljs-type">Tokens</span> (<span class="hljs-type">NonEmpty</span> t)      <span class="hljs-comment">-- ^ Non-empty stream of tokens</span>
  | <span class="hljs-type">Label</span> (<span class="hljs-type">NonEmpty</span> <span class="hljs-type">Char</span>)    <span class="hljs-comment">-- ^ Label (cannot be empty)</span>
  | <span class="hljs-type">EndOfInput</span>               <span class="hljs-comment">-- ^ End of input</span>
</code></pre>
      <p style="margin: 1.2em 0px ! important;">Here <code style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">NonEmpty Char</code>
        stands for “non-empty string”. Without the <code style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">IsString</code>
        instance users are forced to write non-empty strings in an
        inconvenient and awkward-looking way (e.g. <code style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">Label ('f' :| "oobar")</code>);
        the instance makes <code style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">Label "foobar"</code>
        an acceptable notation, thus making the <code style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">NonEmpty Char</code>
        type more viable for use in libraries and user-facing APIs.</p>
      <h3 id="implementation" style="margin: 1.3em 0px 1em; padding:
        0px; font-weight: bold;font-size: 1.3em;">Implementation</h3>
      <p style="margin: 1.2em 0px ! important;">Here’s a sample
        implementation:</p>
      <pre style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code class="hljs language-haskell" style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block ! important;display: block; padding: 0.5em; color: rgb(51, 51, 51); background: rgb(248, 248, 255) none repeat scroll 0% 0%;"><span class="hljs-class"><span class="hljs-keyword">instance</span> <span class="hljs-container">(<span class="hljs-title">a</span> ~ <span class="hljs-type">Char</span>)</span> => <span class="hljs-type">IsString</span> <span class="hljs-container">(<span class="hljs-type">NonEmpty</span> <span class="hljs-title">a</span>)</span> <span class="hljs-keyword">where</span></span>
  fromString (a:<span class="hljs-keyword">as</span>) = a :| <span class="hljs-keyword">as</span>
  fromString <span class="hljs-string">""</span> = errorWithoutStackTrace <span class="hljs-string">"NonEmpty.fromString: empty string"</span>
</code></pre>
      <p style="margin: 1.2em 0px ! important;">This mirrors the <code style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">IsList</code>
        instance for <code style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">NonEmpty</code>.
        (The reason I haven’t used <code style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">fromList</code>
        is that I want the error message to say “fromString” instead of
        “fromList”.)</p>
      <p style="margin: 1.2em 0px ! important;">If this is accepted, I
        can make a patch.</p>
      <div
title="MDH:PHA+IyMjIHRsO2RyPC9wPjxwPldlIGhhdmUgYGluc3RhbmNlIElzU3RyaW5nIFtDaGFyXWAgYW5kIGBpbnN0YW5jZSBJc0xpc3QgKE5vbkVtcHR5IGEpYC4gTGV0J3MgYWxzbyBoYXZlIGBJc1N0cmlu
ZyAoTm9uRW1wdHkgQ2hhcilgLjxicj48L3A+PHA+IyMjIEJhY2tncm91bmQ8L3A+PHA+YElzU3Ry
aW5nYCBpcyBhIGNsYXNzIHRoYXQgaXMgdXNlZCB3aXRoIHRoZSBgLVhPdmVybG9hZGVkU3RyaW5n
c2AgZXh0ZW5zaW9uIHRvIHN1cHBvcnQgc3RyaW5nIGxpdGVyYWxzIG9mIHR5cGVzIG90aGVyIHRo
YW4gYFN0cmluZ2AgLSBmb3IgaW5zdGFuY2UsIHdpdGggdGhlIGBJc1N0cmluZyBUZXh0YCBpbnN0
YW5jZSBpbiBzY29wZSwgeW91IGNhbiB3cml0ZSBgImZvb2JhciIgOjogVGV4dGAgYW5kIGl0IHdp
bGwgY29tcGlsZS48L3A+PHA+Rm9yIHJlZmVyZW5jZSwgdGhlIHN0YW5kYXJkIGxpYnJhcmllcyBz
dXBwbHkgdGhlIGZvbGxvd2luZyBpbnN0YW5jZXMgb2YgYElzU3RyaW5nYDo8L3A+PHA+YGBgaGFz
a2VsbDxicj5pbnN0YW5jZSAoYSB+IENoYXIpID0mZ3Q7IElzU3RyaW5nIFthXTxicj5pbnN0YW5j
ZSBJc1N0cmluZyBhID0mZ3Q7IElzU3RyaW5nIChDb25zdCBhIGIpPGJyPmluc3RhbmNlIElzU3Ry
aW5nIGEgPSZndDsgSXNTdHJpbmcgKElkZW50aXR5IGEpPGJyPmBgYDwvcD48cD4jIyMgUHJvcG9z
YWw8L3A+PHA+SSBwcm9wb3NlIGFkZGluZyBhIG5ldyBpbnN0YW5jZSBvZiBgSXNTdHJpbmdgIGZv
ciBgTm9uRW1wdHlgIGxpc3RzIG9mIGNoYXJhY3RlcnMuIGBOb25FbXB0eWAgaGFzIGJlZW4gaW4g
YGJhc2VgIHN0YXJ0aW5nIGZyb20gdmVyc2lvbiA0LjksIGFuZCBmb3IgdGhhdCByZWFzb24gcGVv
cGxlIGFyZSBzdGFydGluZyB0byB1c2UgaXQgbW9yZSBvZnRlbiAtIGUuZy4gdGhlIHBvcHVsYXIg
YG1lZ2FwYXJzZWNgIGxpYnJhcnkgZGVmaW5lcyBpdHMgY3VzdG9tIGVycm9yIHR5cGUgbGlrZSB0
aGlzOjwvcD48cD5gYGBoYXNrZWxsPGJyPmRhdGEgRXJyb3JJdGVtIHQ8YnI+Jm5ic3A7ID0gVG9r
ZW5zIChOb25FbXB0eSB0KSZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyAtLSBeIE5vbi1l
bXB0eSBzdHJlYW0gb2YgdG9rZW5zPGJyPiZuYnNwOyB8IExhYmVsIChOb25FbXB0eSBDaGFyKSZu
YnNwOyZuYnNwOyZuYnNwOyAtLSBeIExhYmVsIChjYW5ub3QgYmUgZW1wdHkpPGJyPiZuYnNwOyB8
IEVuZE9mSW5wdXQmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz
cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgLS0gXiBFbmQgb2YgaW5wdXQ8
YnI+YGBgPC9wPjxwPkhlcmUgYE5vbkVtcHR5IENoYXJgIHN0YW5kcyBmb3IgIm5vbi1lbXB0eSBz
dHJpbmciLiBXaXRob3V0IHRoZSBgSXNTdHJpbmdgIGluc3RhbmNlIHVzZXJzIGFyZSBmb3JjZWQg
dG8gd3JpdGUgbm9uLWVtcHR5IHN0cmluZ3MgaW4gYW4gaW5jb252ZW5pZW50IGFuZCBhd2t3YXJk
LWxvb2tpbmcgd2F5IChlLmcuIGBMYWJlbCAoJ2YnIDp8ICJvb2JhciIpYCk7IHRoZSBpbnN0YW5j
ZSBtYWtlcyBgTGFiZWwgImZvb2JhciJgIGFuIGFjY2VwdGFibGUgbm90YXRpb24sIHRodXMgbWFr
aW5nIHRoZSBgTm9uRW1wdHkgQ2hhcmAgdHlwZSBtb3JlIHZpYWJsZSBmb3IgdXNlIGluIGxpYnJh
cmllcyBhbmQgdXNlci1mYWNpbmcgQVBJcy48YnI+PC9wPjxwPiMjIyBJbXBsZW1lbnRhdGlvbjwv
cD48cD5IZXJlJ3MgYSBzYW1wbGUgaW1wbGVtZW50YXRpb246PGJyPjwvcD48cD5gYGBoYXNrZWxs
PGJyPmluc3RhbmNlIChhIH4gQ2hhcikgPSZndDsgSXNTdHJpbmcgKE5vbkVtcHR5IGEpIHdoZXJl
PGJyPiZuYnNwOyBmcm9tU3RyaW5nIChhOmFzKSA9IGEgOnwgYXM8YnI+Jm5ic3A7IGZyb21TdHJp
bmcgIiIgPSBlcnJvcldpdGhvdXRTdGFja1RyYWNlICJOb25FbXB0eS5mcm9tU3RyaW5nOiBlbXB0
eSBzdHJpbmciPGJyPmBgYDwvcD48cD5UaGlzIG1pcnJvcnMgdGhlIGBJc0xpc3RgIGluc3RhbmNl
IGZvciBgTm9uRW1wdHlgLiAoVGhlIHJlYXNvbiBJIGhhdmVuJ3QgdXNlZCBgZnJvbUxpc3RgIGlz
IHRoYXQgSSB3YW50IHRoZSBlcnJvciBtZXNzYWdlIHRvIHNheSAiZnJvbVN0cmluZyIgaW5zdGVh
ZCBvZiAiZnJvbUxpc3QiLik8L3A+PHA+SWYgdGhpcyBpcyBhY2NlcHRlZCwgSSBjYW4gbWFrZSBh
        IHBhdGNoLjwvcD4="
style="height:0;width:0;max-height:0;max-width:0;overflow:hidden;font-size:0em;padding:0;margin:0;">​</div>
    </div>
  </body>
</html>