<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p>Idris allows such abstractions in much the same way Haskell does.
ATS allows monads via template (see e.g.
<a class="moz-txt-link-freetext" href="https://github.com/githwxi/ATS-Postiats/blob/e83a467485857d568e20512b486ee52b4b4da97a/libats/ML/DATS/SHARE/monad.hats">https://github.com/githwxi/ATS-Postiats/blob/e83a467485857d568e20512b486ee52b4b4da97a/libats/ML/DATS/SHARE/monad.hats</a>)
but they're kind of broken in practice in that you can have only
instance per executable/library (!)<br>
</p>
<br>
<div class="moz-cite-prefix">On 07/11/2018 11:24 AM, Simon Peyton
Jones via Haskell-Cafe wrote:<br>
</div>
<blockquote type="cite"
cite="mid:AM0PR83MB030832C8CAA921B2B41DC879AD5A0@AM0PR83MB0308.EURPRD83.prod.outlook.com">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered
medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
margin-bottom:.0001pt;
font-size:11.0pt;
font-family:"Calibri",sans-serif;
color:black;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
p.Code, li.Code, div.Code
{mso-style-name:Code;
margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:36.0pt;
margin-bottom:.0001pt;
font-size:9.0pt;
font-family:"Courier New";
color:black;}
p.msonormal0, li.msonormal0, div.msonormal0
{mso-style-name:msonormal;
mso-margin-top-alt:auto;
margin-right:0cm;
mso-margin-bottom-alt:auto;
margin-left:0cm;
font-size:11.0pt;
font-family:"Calibri",sans-serif;
color:black;}
span.EmailStyle19
{mso-style-type:personal-reply;
font-family:"Calibri",sans-serif;
color:windowtext;
font-weight:normal;
font-style:normal;
text-decoration:none none;}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;}
@page WordSection1
{size:612.0pt 792.0pt;
margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
<div class="WordSection1">
<p class="MsoNormal" style="margin-left:36.0pt">Also, languages
are borrowing from each other at a rapid rate these days (eg
Rust traits are equivalent to type classes) so it's hard to
find a "killer feature" in Haskell any more<o:p></o:p></p>
<p class="MsoNormal"><span
style="font-size:12.0pt;color:windowtext"><o:p> </o:p></span></p>
<p class="MsoNormal"><span
style="font-size:12.0pt;color:windowtext">That’s true, and
to be celebrated!<o:p></o:p></span></p>
<p class="MsoNormal"><span
style="font-size:12.0pt;color:windowtext"><o:p> </o:p></span></p>
<p class="MsoNormal"><span
style="font-size:12.0pt;color:windowtext">One thing that
stands our for me is the ability to abstract over type
<b>constructors</b>:<o:p></o:p></span></p>
<p class="MsoNormal"><span
style="font-size:12.0pt;color:windowtext"> f ::
forall (m :: * -> *) (a :: *). Monad m => a -> m a<o:p></o:p></span></p>
<p class="MsoNormal"><span
style="font-size:12.0pt;color:windowtext"><o:p> </o:p></span></p>
<p class="MsoNormal"><span
style="font-size:12.0pt;color:windowtext">That ability is
what has given rise to a stunningly huge collection of
abstractions: not just Monad, but Functor, Applicative,
Traversable, Foldable, etc etc etc. Really a lot. It
opens up a new way to think about the world. But only made
possible by that one feature. (Plus type classes of
course.)<o:p></o:p></span></p>
<p class="MsoNormal"><span
style="font-size:12.0pt;color:windowtext"><o:p> </o:p></span></p>
<p class="MsoNormal"><span
style="font-size:12.0pt;color:windowtext">Do any statically
typed languages other than Haskell and Scala do this?<o:p></o:p></span></p>
<p class="MsoNormal"><span
style="font-size:12.0pt;color:windowtext"><o:p> </o:p></span></p>
<p class="MsoNormal"><span
style="font-size:12.0pt;color:windowtext">Simon<o:p></o:p></span></p>
<p class="MsoNormal"><span
style="font-size:12.0pt;color:windowtext"><o:p> </o:p></span></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0cm
0cm 0cm 4.0pt">
<div>
<div style="border:none;border-top:solid #E1E1E1
1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal"><b><span style="color:windowtext"
lang="EN-US">From:</span></b><span
style="color:windowtext" lang="EN-US"> Haskell-Cafe
<a class="moz-txt-link-rfc2396E" href="mailto:haskell-cafe-bounces@haskell.org"><haskell-cafe-bounces@haskell.org></a>
<b>On Behalf Of </b>Neil Mayhew<br>
<b>Sent:</b> 11 July 2018 17:12<br>
<b>To:</b> Haskell Cafe
<a class="moz-txt-link-rfc2396E" href="mailto:haskell-cafe@haskell.org"><haskell-cafe@haskell.org></a><br>
<b>Subject:</b> Re: [Haskell-cafe] What is your
favourite Haskell "aha" moment?<o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I came to Haskell from C++, and I was
used to the idea of parametric types and functions from C++
templates.<br>
<br>
However, what I really liked about Haskell's way of doing
these was that, due to type inference, not only is there a
lot less ceremony involved, but code is generic (parametric)
*by default*, and thus much more reusable, although you
still have the option of tightening it up by adding a type
annotation (eg for performance reasons). For a while, I was
writing all my C++ code as templates, but this ended up
being a pain.<br>
<br>
Also, traditionally C++ has not allowed you to place any
constraints on template arguments (type parameters) whereas
Haskell's type classes are a very elegant way of doing it.
(C++ now has concepts, but I haven't taken the time yet to
see how they compare with type classes.)<br>
<br>
I was also used to function overloading, which is somewhat
similar to type inference, in that the compiler will pick an
implementation based on the types of a function's arguments.
This is similar to Haskell picking an implementation from
among type class instances. However, what blew me away is
that Haskell can overload based on *return type* as well as
argument types. I haven't seen any other production-ready
language that can do this. A great example of how this is
useful is the regex library, where you can select from among
widely varying styles of regex matching result simply by
type inference, ie without needing any type annotation.<br>
<br>
There were a *lot* of other things I found amazing, but
others have covered many of these already. Also, languages
are borrowing from each other at a rapid rate these days (eg
Rust traits are equivalent to type classes) so it's hard to
find a "killer feature" in Haskell any more (except
laziness, perhaps). I think it's more the well-balanced
combination of all the features that makes Haskell so
pleasant to work in, and it's hard to demonstrate all of
these in a single example.<br>
<br>
My own favourite "gem" is this code for computing all
primes, based on code in a paper[1] by Doug McIlroy:<br>
<br>
primes = sieve [2..] where sieve (p : ns) = p : sieve [n | n
<- ns, n `mod` p /= 0]<br>
<br>
I think care must be exercised, when using examples like
this one, to avoid giving the impression that Haskell is a
"toy" language. However, what I find interesting about this
example is that all other sieve implementations I've seen
work on a fixed size of sieve up front, and if you later
change your mind about how many primes you want, eg because
you're expanding a hash table and want a bigger prime for
the size, you typically have to start the sieve from scratch
again.<br>
<br>
[1]: <a
href="https://na01.safelinks.protection.outlook.com/?url=http:%2F%2Fwww.cs.dartmouth.edu%2F%7Edoug%2Fsieve%2Fsieve.pdf&data=02%7C01%7Csimonpj%40microsoft.com%7Cce59cb95fe304d442b8d08d5e7490739%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636669223196857658&sdata=1UGE8hoL8B9yMjXqJbe5HV%2FsAXlpoB653kePOrgpCNY%3D&reserved=0"
moz-do-not-send="true">
http://www.cs.dartmouth.edu/~doug/sieve/sieve.pdf</a><o:p></o:p></p>
</div>
</div>
<!--'"--><br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<br>
<pre wrap="">_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
<a class="moz-txt-link-freetext" href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a>
Only members subscribed via the mailman list are allowed to post.</pre>
</blockquote>
</body>
</html>