<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p>Why not:</p>
<p>class isString1 a where fromString1 :: NonEmpty Char -> a<br>
</p>
<br>
<div class="moz-cite-prefix">On 02/09/17 22:08, Artyom wrote:<br>
</div>
<blockquote type="cite"
cite="mid:917f9546-b586-8d73-09b9-d8eefb37d87a@artyom.me">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<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+IyMjIHRsO2RyPC9wPjxwPldlIGhhdmUgYGluc3RhbmNlIElzU3RyaW5nIFtDaGFyXWAgYW5kIGBpbnN0YW5jZSBJc0xpc3QgKE5vbkVtcHR5IGEpYC4gTGV0J3MgYWxzbyBoYXZlIGBJc1N0cmluZyAoTm9uRW1wdHkgQ2hhcilgLjxicj48L3A+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>
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<br>
<pre wrap="">_______________________________________________
Libraries mailing list
<a class="moz-txt-link-abbreviated" href="mailto:Libraries@haskell.org">Libraries@haskell.org</a>
<a class="moz-txt-link-freetext" href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a>
</pre>
</blockquote>
<br>
</body>
</html>