
Okay, so how about the following as a user narrative for some and many? many v = repeatedly execute the action v and save each obtained result until v fails; at that point, *succeed* and return a list with all of the results that had been collected some v = like many v, but if v does not succeed even once then *fail* instead of return the empty list Note: If v *never* fails, then at best many/some will return infinite lists, and at worst they will repeat your action forever. Cheers, Greg P.S.: And yes, I know that many of you will complain that these definitions are not mathematically precise or what not, but it is important to be able to build up narratives at a sufficiently high level that they explain the essentials of what is going on for the benefit of users who are unfamiliar with the precise mathematical language used to precisely define their semantics.

Okay, so how about the following as a user narrative for some and many?
...
I was in the middle of writing my own version of Applicative when I stumbled on this intense debate. Here's what I wrote for the documentation: class (Applicative f, Monoid f) => Alternative f where -- | Keep repeating the action (consuming its values) until it fails, and then return the values consumed. -- -- [Warning]: This is only defined for actions that eventually fail -- after being performed repeatedly, such as parsing. For pure values such -- as 'Maybe', this will cause an infinite loop. some :: f a -> f [a] some v = ... -- | Similar to 'many', but if no values are consumed it returns 'empty' instead of @f []@. -- -- [Warning]: This is only defined for actions that eventually fail -- after being performed repeatedly, such as parsing. For pure values such -- as 'Maybe', this will cause an infinite loop. many :: f a -> f [a] many v = ... Warnings are repeated for emphasis :)

On Dec 15, 2011, at 4:29 PM, Chris Wong wrote:
Okay, so how about the following as a user narrative for some and many?
...
I was in the middle of writing my own version of Applicative when I stumbled on this intense debate. Here's what I wrote for the documentation:
class (Applicative f, Monoid f) => Alternative f where -- | Keep repeating the action (consuming its values) until it fails, and then return the values consumed. -- -- [Warning]: This is only defined for actions that eventually fail -- after being performed repeatedly, such as parsing. For pure values such -- as 'Maybe', this will cause an infinite loop. some :: f a -> f [a] some v = ...
-- | Similar to 'many', but if no values are consumed it returns 'empty' instead of @f []@. -- -- [Warning]: This is only defined for actions that eventually fail -- after being performed repeatedly, such as parsing. For pure values such -- as 'Maybe', this will cause an infinite loop. many :: f a -> f [a] many v = ...
Warnings are repeated for emphasis :)
I think that merely putting up documentation along these lines would be a huge improvement, though it should also contain the formal definitions from the old documentation in it somewhere as well. Cheers, Greg

On Thu, Dec 15, 2011 at 07:29:20PM +1300, Chris Wong wrote:
Okay, so how about the following as a user narrative for some and many?
...
I was in the middle of writing my own version of Applicative when I stumbled on this intense debate. Here's what I wrote for the documentation:
class (Applicative f, Monoid f) => Alternative f where
Note that 'Monoid f' does not make sense, since the kinds do not match. Perhaps what you mean is (forall a. Monoid (f a)) but that is (currently) impossible to express. One could, of course, make a new typeclass class Monoid1 f where mempty1 :: f a mappend1 :: f a -> f a -> f a -Brent

On 15 December 2011 06:29, Chris Wong
class (Applicative f, Monoid f) => Alternative f where -- | Keep repeating the action (consuming its values) until it fails, and then return the values consumed.
I think this should be "collect" rather than "consume" and you can omit the parentheses. I also think that we should include the original definition, which is more formally precise (although it could use with some examples).
-- -- [Warning]: This is only defined for actions that eventually fail
Perhaps add the remark that we expect non-deterministic actions.
-- after being performed repeatedly, such as parsing. For pure values such -- as 'Maybe', this will cause an infinite loop. some :: f a -> f [a] some v = ...
-- | Similar to 'many', but if no values are consumed it returns 'empty' instead of @f []@. -- -- [Warning]: This is only defined for actions that eventually fail -- after being performed repeatedly, such as parsing. For pure values such -- as 'Maybe', this will cause an infinite loop. many :: f a -> f [a] many v = ...
Warnings are repeated for emphasis :)
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Push the envelope. Watch it bend.

On Wed, Dec 14, 2011 at 10:29 PM, Chris Wong < chrisyco+haskell-cafe@gmail.com> wrote:
-- [Warning]: This is only defined for actions that eventually fail -- after being performed repeatedly, such as parsing. For pure values such -- as 'Maybe', this will cause an infinite loop.
This is both confusing and incorrect. It's entirely possible for an action in the Maybe type to fail. For the Maybe type, "failing" means an action returns Nothing, and "succeeding" means an action returns Just (some value). If an action of type Maybe a is written to always and unconditionally return Just some-value-or-other, *that's* when some or many will infinite-loop if used with it. That doesn't mean there's something wrong with the definitions of some or many, but rather that they need to be supplied with an action that will at some point fail.

On Dec 16, 2011, at 3:34 AM, Bryan O'Sullivan wrote:
This is both confusing and incorrect. It's entirely possible for an action in the Maybe type to fail.
Okay, so inserting the phrases "that either fail eventually or" and "that succeed forever if they do not immediately fail" so that that the documentation reads: -- [Warning]: This is only defined for actions that either fail immediately or that eventually fail -- after being performed repeatedly, such as parsing. For pure values such -- as 'Maybe' that succeed forever if they do not immediately fail, this will cause an infinite loop. makes the situation more clear. Cheers, Greg

On Thu, Dec 15, 2011 at 09:34:14AM -0800, Bryan O'Sullivan wrote:
On Wed, Dec 14, 2011 at 10:29 PM, Chris Wong < chrisyco+haskell-cafe@gmail.com> wrote:
-- [Warning]: This is only defined for actions that eventually fail -- after being performed repeatedly, such as parsing. For pure values such -- as 'Maybe', this will cause an infinite loop.
If an action of type Maybe a is written to always and unconditionally return Just some-value-or-other, *that's* when some or many will
The way you phrased this sounds odd to me. Every action/value of type Maybe a will *either* "always and unconditionally" be Nothing, OR always and unconditionally be Just some-value-or-other. By referential transparency, those are the only options. -Brent
participants (5)
-
Brent Yorgey
-
Bryan O'Sullivan
-
Chris Wong
-
Gregory Crosswhite
-
Thomas Schilling