<div dir="ltr"><div><div><div>In (my) most to least preferred:<br><br></div>* NonEmpty#singleton<br></div>* <doesn't exist at all><br></div><div>* []#singleton</div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Aug 23, 2019 at 3:12 AM Kris Nuttycombe <<a href="mailto:kris.nuttycombe@gmail.com">kris.nuttycombe@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"></div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Aug 22, 2019 at 3:58 AM Sven Panne <<a href="mailto:svenpanne@gmail.com" target="_blank">svenpanne@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><div dir="ltr" class="gmail_attr">I think the main problem of this discussion (and other similar threads on this list) is that there is no consensus about how to design an API. IMHO, piling up little helpers just because they came up in a few places is a recipe for horrible, bloated APIs. The questions one should ask are "Does it generalize things?", "Does it make my API more powerful?" (i.e. can I do things I couldn't do before), "Does it remove common pitfalls?" etc.  But this is just my personal view, obviously others seem to disagree.... :-/</div></div></div></blockquote><div><br> I think there's a significant difference between "little helper" and "the monomorphic function that is used to implement `pure`" - with a slightly different framing, we might be able to come to an agreement that both the monomorphic an polymorphic versions of this function are useful in different contexts. <br><br><a href="https://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Base.html#line-972" target="_blank">https://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Base.html#line-972</a><br><br>We define a monomorphic function for this operation, we just hide it in the implementation of the typeclass instance; we do this frequently, intentionally making a monomorphic function inaccessible to the user unless it's called in a polymorphic context (and, if they want to intentionally monomorphise it, require using an extension - type applications - which is particularly ugly/inconvenient for operators like `>>=`.) I think this is unfortunate as a general design choice; the user of a library should have the flexibility to choose, not be forced into one or the other. For [] we have the robot monkey operator, and this is an idiom that people can become familiar with - but it does not appear natively in any documentation; it is a partially applied constructor rather than a top-level function.<br><br>My guiding principle for API design is that one should always expose the fundamental building blocks as a low-level API, and then provide a smaller interface for the common use cases. Typeclass instances are no different - they are the general interface that allows us to invoke what is ultimately a monomorphic, low-level building block function in a polymorphic context. </div><div><br></div><div>Kris</div></div></div>
_______________________________________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a><br>
</blockquote></div>