Haskell reference documentation, laws first or laws last?

On Thu, Sep 16, 2021 at 06:51:42PM -0400, David Feuer wrote:
The last time I went to look at the laws it took me a couple minutes to find them. I use them to write instances. Pretty important, IMO.
I agree the laws are important to document, I just don't think they belong at the top of the module. The beginner to intermediate users will be using the library and existing instances for some time before they start to write their own instances. If more modules adopt something like the style of the new Data.Foldable, experienced users will know to look for the laws at the end, if not still present at the top of the module. Of course perhaps the community would prefer the original Laws first format, I'm fine with that emerging as the consensus. Perhaps worthy of a separate thread (made it so). Of course the conjectured users who might most benefit from not being intimidated by being exposed to laws before they're ready to understand them might not be present on this forum... -- Viktor.

For what it's worth, I agree with you both that it's important to document
the laws, and that it's not the most friendly way to begin the
documentation for a reader who is unfamiliar with the concept. It's not
clear to me whether the documentation ought to be optimized for readers who
are or aren't familiar with the concept, but I lean to the latter, which
means putting the type class laws at the end (but still easily accessible)
makes sense to me.
On Thu, Sep 16, 2021 at 7:47 PM Viktor Dukhovni
On Thu, Sep 16, 2021 at 06:51:42PM -0400, David Feuer wrote:
The last time I went to look at the laws it took me a couple minutes to find them. I use them to write instances. Pretty important, IMO.
I agree the laws are important to document, I just don't think they belong at the top of the module. The beginner to intermediate users will be using the library and existing instances for some time before they start to write their own instances.
If more modules adopt something like the style of the new Data.Foldable, experienced users will know to look for the laws at the end, if not still present at the top of the module.
Of course perhaps the community would prefer the original Laws first format, I'm fine with that emerging as the consensus. Perhaps worthy of a separate thread (made it so).
Of course the conjectured users who might most benefit from not being intimidated by being exposed to laws before they're ready to understand them might not be present on this forum...
-- Viktor. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

I'm not talking about whether they're first or last. They're currently not
part of the class documentation *at all*. They're only in the
Data.Traversable documentation.
On Thu, Sep 16, 2021, 7:45 PM Viktor Dukhovni
On Thu, Sep 16, 2021 at 06:51:42PM -0400, David Feuer wrote:
The last time I went to look at the laws it took me a couple minutes to find them. I use them to write instances. Pretty important, IMO.
I agree the laws are important to document, I just don't think they belong at the top of the module. The beginner to intermediate users will be using the library and existing instances for some time before they start to write their own instances.
If more modules adopt something like the style of the new Data.Foldable, experienced users will know to look for the laws at the end, if not still present at the top of the module.
Of course perhaps the community would prefer the original Laws first format, I'm fine with that emerging as the consensus. Perhaps worthy of a separate thread (made it so).
Of course the conjectured users who might most benefit from not being intimidated by being exposed to laws before they're ready to understand them might not be present on this forum...
-- Viktor. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

On Thu, Sep 16, 2021 at 09:14:19PM -0400, David Feuer wrote:
I'm not talking about whether they're first or last. They're currently not part of the class documentation *at all*. They're only in the Data.Traversable documentation.
I see, I think you're noting that when re-exported from Prelude, the class definitions of Foldable and Traversable that appear in the Prelude module: https://hackage.haskell.org/package/base-4.15.0.0/docs/Prelude.html#g:11 no longer include the laws, you have to look at the underlying module to find them. If that's the issue, I should note that the re-exported class definitions do have overview hyperlinks: A more detailed description can be found in the overview section of [Data.Foldable](https://hackage.haskell.org/package/base-4.15.0.0/docs/Data-Foldable.html#ov...) A more detailed description can be found in the overview section of [Data.Traversable](https://hackage.haskell.org/package/base-4.15.0.0/docs/Data-Traversable.html...) Would your issue be addressed if links to the laws were similarly linked from the class definitions? -- Viktor.

The laws of any sensible class are an essential and integral part of it.
Without them, you just have ad hoc overloading. They shouldn't be relegated
to the canonical exporting module.
On Thu, Sep 16, 2021, 9:27 PM Viktor Dukhovni
On Thu, Sep 16, 2021 at 09:14:19PM -0400, David Feuer wrote:
I'm not talking about whether they're first or last. They're currently not part of the class documentation *at all*. They're only in the Data.Traversable documentation.
I see, I think you're noting that when re-exported from Prelude, the class definitions of Foldable and Traversable that appear in the Prelude module:
https://hackage.haskell.org/package/base-4.15.0.0/docs/Prelude.html#g:11
no longer include the laws, you have to look at the underlying module to find them. If that's the issue, I should note that the re-exported class definitions do have overview hyperlinks:
A more detailed description can be found in the overview section of [Data.Foldable]( https://hackage.haskell.org/package/base-4.15.0.0/docs/Data-Foldable.html#ov... )
A more detailed description can be found in the overview section of [Data.Traversable]( https://hackage.haskell.org/package/base-4.15.0.0/docs/Data-Traversable.html... )
Would your issue be addressed if links to the laws were similarly linked from the class definitions?
-- Viktor. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

On 16 Sep 2021, at 9:33 pm, David Feuer
wrote: The laws of any sensible class are an essential and integral part of it. Without them, you just have ad hoc overloading. They shouldn't be relegated to the canonical exporting module.
Surely a one click link from the Prelude re-export is no worse than a 1-click link in the module table of contents? I am rather reluctant beat new readers over the head with laws that often are much too abstract to add clarity. -- Viktor.

On Thu, Sep 16, 2021 at 09:56:37PM -0400, Viktor Dukhovni wrote:
Surely a one click link from the Prelude re-export is no worse than a 1-click link in the module table of contents?
I am rather reluctant beat new readers over the head with laws that often are much too abstract to add clarity.
I've opened an MR: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/6555 that adds a "Laws" link to the class head haddocks, and attempts to improve some prose that was found a bit wanting in the recent threads. https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Prelude... https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Fo... The Overview of Data.Foldable is aimed at a novice to intermediate Haskell programmer, not a complete beginner or someone long familiar with the ins and outs of folds. The idea is to help the reader be able to reason about the various Foldable methods and choose the right one for the task at hand. Maybe, though not the main intent, to write better Foldable instances (if not simply derived). Perhaps the intended audience should be explicitly stated, to save complete beginners who are not ready for it, or seasoned Haskellers who don't need it the trouble of figuring out whether the content is for them??? -- Viktor.

I'll try to take a look. When writing instances (which I consider a
beginner-level activity), it's really important to learn to follow the
laws. While that may just sound like a bunch of theory, it turns out that
in practice violating typeclass laws leads to seriously unintuitive
behavior, breaking the expectations users have developed after using many
instances.
On Sat, Sep 18, 2021, 9:47 PM Viktor Dukhovni
On Thu, Sep 16, 2021 at 09:56:37PM -0400, Viktor Dukhovni wrote:
Surely a one click link from the Prelude re-export is no worse than a 1-click link in the module table of contents?
I am rather reluctant beat new readers over the head with laws that often are much too abstract to add clarity.
I've opened an MR: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/6555
that adds a "Laws" link to the class head haddocks, and attempts to improve some prose that was found a bit wanting in the recent threads.
https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Prelude...
https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Fo...
The Overview of Data.Foldable is aimed at a novice to intermediate Haskell programmer, not a complete beginner or someone long familiar with the ins and outs of folds. The idea is to help the reader be able to reason about the various Foldable methods and choose the right one for the task at hand. Maybe, though not the main intent, to write better Foldable instances (if not simply derived).
Perhaps the intended audience should be explicitly stated, to save complete beginners who are not ready for it, or seasoned Haskellers who don't need it the trouble of figuring out whether the content is for them???
-- Viktor. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

On Sat, Sep 18, 2021 at 09:57:09PM -0400, David Feuer wrote:
I'll try to take a look. When writing instances (which I consider a beginner-level activity), it's really important to learn to follow the laws. While that may just sound like a bunch of theory, it turns out that in practice violating typeclass laws leads to seriously unintuitive behavior, breaking the expectations users have developed after using many instances.
If that's the intent, the laws for Foldable need a substantially better explanation that the given equations, which shed very little light on the actual requirements. It would probably be most productive to add new prose explaining the laws to the "Defining instances" section: https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Fo... and reference the laws also from there, if someone wants the concise form for QuickCheck property tests or the like. I am no longer a novice, and yet would still have a hard time making any use of the laws as written in constructing instances. Instead, I'd ignore the laws and write a natural intuitive instance, and it would invariably work. The text in "Definining Instances" aims to help readers ensure the implementations are reasonably efficient, but presently does not drag in the laws. As the author of the laws section, perhaps you'd be willing to contribute explanatory prose??? -- Viktor.

Foldable doesn't have much in the way of interesting laws, really. And I'm
not sure how to make the relationships between foldMap, foldr, foldl,
foldr', and foldl' clear to beginners. I'll have to think on that a bit.
foldMap unifies finite, left-finite, right-finite, and doubly infinite
structures, which is a tricky thing to explain to beginners!
On Sun, Sep 19, 2021, 12:14 AM Viktor Dukhovni
On Sat, Sep 18, 2021 at 09:57:09PM -0400, David Feuer wrote:
I'll try to take a look. When writing instances (which I consider a beginner-level activity), it's really important to learn to follow the laws. While that may just sound like a bunch of theory, it turns out that in practice violating typeclass laws leads to seriously unintuitive behavior, breaking the expectations users have developed after using many instances.
If that's the intent, the laws for Foldable need a substantially better explanation that the given equations, which shed very little light on the actual requirements.
It would probably be most productive to add new prose explaining the laws to the "Defining instances" section:
https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Fo...
and reference the laws also from there, if someone wants the concise form for QuickCheck property tests or the like.
I am no longer a novice, and yet would still have a hard time making any use of the laws as written in constructing instances. Instead, I'd ignore the laws and write a natural intuitive instance, and it would invariably work. The text in "Definining Instances" aims to help readers ensure the implementations are reasonably efficient, but presently does not drag in the laws.
As the author of the laws section, perhaps you'd be willing to contribute explanatory prose???
-- Viktor. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

Ah, I misunderstood you as well. I agree that the laws should be included
in the type class documentation. In fact, most of the documentation from
the link should probably be moved into the documentation for the class,
rather than a stand-alone section.
On Thu, Sep 16, 2021 at 9:15 PM David Feuer
I'm not talking about whether they're first or last. They're currently not part of the class documentation *at all*. They're only in the Data.Traversable documentation.
On Thu, Sep 16, 2021, 7:45 PM Viktor Dukhovni
wrote: On Thu, Sep 16, 2021 at 06:51:42PM -0400, David Feuer wrote:
The last time I went to look at the laws it took me a couple minutes to find them. I use them to write instances. Pretty important, IMO.
I agree the laws are important to document, I just don't think they belong at the top of the module. The beginner to intermediate users will be using the library and existing instances for some time before they start to write their own instances.
If more modules adopt something like the style of the new Data.Foldable, experienced users will know to look for the laws at the end, if not still present at the top of the module.
Of course perhaps the community would prefer the original Laws first format, I'm fine with that emerging as the consensus. Perhaps worthy of a separate thread (made it so).
Of course the conjectured users who might most benefit from not being intimidated by being exposed to laws before they're ready to understand them might not be present on this forum...
-- Viktor. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

I personally like it if the documentation of re-exported classes just
contain a summary, much like Data.Foldable does. The prelude documentation
is quite long already. I would not object to making the links stand out a
bit more though: a title 'More detailed descriptions' with a bulleted
summary to 'laws' might do that.
On where the laws need to be: I think for foldable the right decision is
made, there may be exceptions but I typically like to hear about the ideas
behind things before I dive into the algebraic characterization.
Also, many thanks to the write-up of Foldable.
Best,
Sebastiaan
On Thu, Sep 16, 2021 at 9:36 PM Chris Smith
Ah, I misunderstood you as well. I agree that the laws should be included in the type class documentation. In fact, most of the documentation from the link should probably be moved into the documentation for the class, rather than a stand-alone section.
On Thu, Sep 16, 2021 at 9:15 PM David Feuer
wrote: I'm not talking about whether they're first or last. They're currently not part of the class documentation *at all*. They're only in the Data.Traversable documentation.
On Thu, Sep 16, 2021, 7:45 PM Viktor Dukhovni
wrote: On Thu, Sep 16, 2021 at 06:51:42PM -0400, David Feuer wrote:
The last time I went to look at the laws it took me a couple minutes to find them. I use them to write instances. Pretty important, IMO.
I agree the laws are important to document, I just don't think they belong at the top of the module. The beginner to intermediate users will be using the library and existing instances for some time before they start to write their own instances.
If more modules adopt something like the style of the new Data.Foldable, experienced users will know to look for the laws at the end, if not still present at the top of the module.
Of course perhaps the community would prefer the original Laws first format, I'm fine with that emerging as the consensus. Perhaps worthy of a separate thread (made it so).
Of course the conjectured users who might most benefit from not being intimidated by being exposed to laws before they're ready to understand them might not be present on this forum...
-- Viktor. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

Hello Viktor.
Thank you for your continuous effort.
I have been writing Haskell for years now and even getting paid for
it. I care nothing for the laws — I rarely apply equational reasoning.
I am a visual person, to me intuitive grasp is the tool of choice. I
also know a few newcomers to Haskell and I am certain they make zero
use of the laws.
My thus informed view is that laws are fine in the end and useless at the start.
On Fri, 17 Sept 2021 at 04:48, Viktor Dukhovni
On Thu, Sep 16, 2021 at 06:51:42PM -0400, David Feuer wrote:
The last time I went to look at the laws it took me a couple minutes to find them. I use them to write instances. Pretty important, IMO.
I agree the laws are important to document, I just don't think they belong at the top of the module. The beginner to intermediate users will be using the library and existing instances for some time before they start to write their own instances.
If more modules adopt something like the style of the new Data.Foldable, experienced users will know to look for the laws at the end, if not still present at the top of the module.
Of course perhaps the community would prefer the original Laws first format, I'm fine with that emerging as the consensus. Perhaps worthy of a separate thread (made it so).
Of course the conjectured users who might most benefit from not being intimidated by being exposed to laws before they're ready to understand them might not be present on this forum...
-- Viktor. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

Perhaps it would make sense to have a 'using the class' section and a 'writing instances' section.
The first would focus on more concrete and intuitive examples.
The second would explain how and why to follow the laws, maybe with specific ways to avoid pitfalls and extra work (e.g. when you can and can't DeriveFoldable, when to use `foldMapDefault` when to define only `foldr` or `foldMap` or to use `toList` to define others.
It's super important that folks gan define legal instances so things don't brow up in their faces (e.g. an Applicative instance that zips but defines `pure` as a singleton). But often all they need to know is `DeriveTraversable` exists and works as long as you don't define things in strange ways (like conceptually reversed lists).
--Keith
Sent from my phone with K-9 Mail.
On 17 September 2021 08:30:37 UTC, Ignat Insarov
Hello Viktor.
Thank you for your continuous effort.
I have been writing Haskell for years now and even getting paid for it. I care nothing for the laws — I rarely apply equational reasoning. I am a visual person, to me intuitive grasp is the tool of choice. I also know a few newcomers to Haskell and I am certain they make zero use of the laws.
My thus informed view is that laws are fine in the end and useless at the start.
On Fri, 17 Sept 2021 at 04:48, Viktor Dukhovni
wrote: On Thu, Sep 16, 2021 at 06:51:42PM -0400, David Feuer wrote:
The last time I went to look at the laws it took me a couple minutes to find them. I use them to write instances. Pretty important, IMO.
I agree the laws are important to document, I just don't think they belong at the top of the module. The beginner to intermediate users will be using the library and existing instances for some time before they start to write their own instances.
If more modules adopt something like the style of the new Data.Foldable, experienced users will know to look for the laws at the end, if not still present at the top of the module.
Of course perhaps the community would prefer the original Laws first format, I'm fine with that emerging as the consensus. Perhaps worthy of a separate thread (made it so).
Of course the conjectured users who might most benefit from not being intimidated by being exposed to laws before they're ready to understand them might not be present on this forum...
-- Viktor. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

Class laws are not only neccessary to write correct instances. They are also extremely important documentation for users! For instance, one of the three Monad laws says that do x <- doSomething return x = doSomething You cannot refactor monadic code without relying on that law. Cheers Ben Am 17.09.21 um 23:04 schrieb Keith:
Perhaps it would make sense to have a 'using the class' section and a 'writing instances' section. The first would focus on more concrete and intuitive examples. The second would explain how and why to follow the laws, maybe with specific ways to avoid pitfalls and extra work (e.g. when you can and can't DeriveFoldable, when to use `foldMapDefault` when to define only `foldr` or `foldMap` or to use `toList` to define others.
It's super important that folks gan define legal instances so things don't brow up in their faces (e.g. an Applicative instance that zips but defines `pure` as a singleton). But often all they need to know is `DeriveTraversable` exists and works as long as you don't define things in strange ways (like conceptually reversed lists). --Keith Sent from my phone with K-9 Mail.
On 17 September 2021 08:30:37 UTC, Ignat Insarov
wrote: Hello Viktor.
Thank you for your continuous effort.
I have been writing Haskell for years now and even getting paid for it. I care nothing for the laws — I rarely apply equational reasoning. I am a visual person, to me intuitive grasp is the tool of choice. I also know a few newcomers to Haskell and I am certain they make zero use of the laws.
My thus informed view is that laws are fine in the end and useless at the start.
On Fri, 17 Sept 2021 at 04:48, Viktor Dukhovni
wrote: On Thu, Sep 16, 2021 at 06:51:42PM -0400, David Feuer wrote:
The last time I went to look at the laws it took me a couple minutes to find them. I use them to write instances. Pretty important, IMO.
I agree the laws are important to document, I just don't think they belong at the top of the module. The beginner to intermediate users will be using the library and existing instances for some time before they start to write their own instances.
If more modules adopt something like the style of the new Data.Foldable, experienced users will know to look for the laws at the end, if not still present at the top of the module.
Of course perhaps the community would prefer the original Laws first format, I'm fine with that emerging as the consensus. Perhaps worthy of a separate thread (made it so).
Of course the conjectured users who might most benefit from not being intimidated by being exposed to laws before they're ready to understand them might not be present on this forum...
-- Viktor. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
-- I would rather have questions that cannot be answered, than answers that cannot be questioned. -- Richard Feynman
participants (7)
-
Ben Franksen
-
Chris Smith
-
David Feuer
-
Ignat Insarov
-
Keith
-
Sebastiaan Joosten
-
Viktor Dukhovni