23 Jan 2013 01:04

```monad-bool implements a pair of Boolean monoids and monads, to support
short-circuiting, value-returning computations similar to what Python and Ruby
offer with their native && and || operators.

For example, in Python you might see this:

x = [1,2,3,0]
print x[1] || x[3]               -- prints "2"

With this library, you can now mirror such code in Haskell:

let x = [1,2,3,0]
print \$ (x !! 1) ||? (x !! 3)   -- prints "Success 2"

"Booleanness" is based on each type having an instance of the
'Control.Conditional.ToBool' type, for which only the basic types are covered
(Bool, Int, Integer, Maybe a, Either a b, [a], Attempt a).  If you wish to
define a truth value for your own types, simply provide an instance for
ToBool:

instance ToBool MyType where
toBool = ...

The And/Or monoids use the Attempt library so that the actual type of the
successful results depends on case analysis.  It could be a list, a Maybe, an
Either, or an exception in the IO Monad.

The monad variants, AndM, AndMT, OrM and OrMT provide short-circuiting
behavior in a Monad, which returns the last value returned before truth was
determined.  Here are two examples:
```

23 Jan 2013 01:12

```
On Tue, 22 Jan 2013, John Wiegley wrote:

> Use 'onlyIf' with AndM and AndMT to guard later statements, which are only
> evaluated if every preceding 'onlyIf' evaluates to True.  For example:
>
>    foo :: AndM Int
>    foo = do onlyIf (True == True)
>             return 100
>             onlyIf (True == True)
>             return 150
>             onlyIf (True == False)
>             return 200
>
> When run with `evalAndM foo (-1)` (where (-1) provides a default value), 'foo'
> returns 150.

(return x) (without a '<-') is a no-op.
```
23 Jan 2013 02:24

```>>>>> Henning Thielemann <lemming <at> henning-thielemann.de> writes:

> (return x) (without a '<-') is a no-op.

You are very right.  I will make the necessary changes.

--

--
John Wiegley
FP Complete                         Haskell tools, training and consulting
```
23 Jan 2013 01:34

```On 23 January 2013 08:04, John Wiegley <johnw <at> fpcomplete.com> wrote:
> monad-bool implements a pair of Boolean monoids and monads, to support
> short-circuiting, value-returning computations similar to what Python and Ruby
> offer with their native && and || operators.
> ...
> Use 'onlyIf' with AndM and AndMT to guard later statements, which are only
> evaluated if every preceding 'onlyIf' evaluates to True.  For example:
>
>     foo :: AndM Int
>     foo = do onlyIf (True == True)
>              return 100
>              onlyIf (True == True)
>              return 150
>              onlyIf (True == False)
>              return 200
>
> When run with `evalAndM foo (-1)` (where (-1) provides a default value), 'foo'
> returns 150.
>
> Use 'endIf' with OrM and OrMT to chain statements, which are only executed if
> every preceding 'endIf' evaluated to False.  For example:
>
>     bar :: OrM Int
>     bar = do endIf (True == False)
>              return 100
>              endIf (True == False)
>              return 150
>              endIf (True == True)
>              return 200

```

23 Jan 2013 02:25

```>>>>> Conrad Parker <conrad <at> metadecks.org> writes:

> these sound powerful, but how would I do something esoteric like
> if/elseIf/endIf ?

Can you show me an example of what you'd like to express?

--

--
John Wiegley
FP Complete                         Haskell tools, training and consulting
```
23 Jan 2013 03:36

```On 23 January 2013 09:25, John Wiegley <johnw <at> fpcomplete.com> wrote:
>
>> these sound powerful, but how would I do something esoteric like
>> if/elseIf/endIf ?
>
> Can you show me an example of what you'd like to express?

Your examples look vaguely like an if/elseif/else block from other
languages, so I was wondering if mimicking that was possible.

Also, can this be used with RebindableSyntax?

```
23 Jan 2013 01:58

```* John Wiegley <johnw <at> fpcomplete.com> [2013-01-22 18:04:36-0600]
> monad-bool implements a pair of Boolean monoids and monads, to support
> short-circuiting, value-returning computations similar to what Python and Ruby
> offer with their native && and || operators.

Random thoughts after compiling/looking at the code:

- your constraint on 'base' is too restrictive — I had to relax it in
order to compile the package (my 'base' is 4.6.0.1, which came with
GHC 7.6.2 RC)

- personally I never missed "0 as False"...

- what do you need unsafeCoerce for?

Roman

_______________________________________________
```
23 Jan 2013 04:13

```Roman Cheplyaka <roma <at> ro-che.info> wrote:

> - what do you need unsafeCoerce for?

The unsafeCoerce is needed because the library is severely broken.
Consider this:

do onlyIf False
x <- c
onlyIf True
return x

There is a good reason why Haskell's type system would never have
allowed to write this library.  I recommend the author to try again
without unsafeCoerce.  It won't work.

Also I'm quite sure that the monads don't have associative (>>) either.
Consider this:

yes = onlyIf True
no  = onlyIf False

yes >> x >> no >> y

According to the intended semantics this should result in 'x', but what
does

yes >> (x >> no) >> y

result in?
```

23 Jan 2013 07:03

```>>>>> Ertugrul Söylemez <es <at> ertes.de> writes:

> There is a good reason why Haskell's type system would never have allowed to
> write this library.  I recommend the author to try again without
> unsafeCoerce.  It won't work.

You are right, and in fact what I wanted to do cannot be done.  It requires
distinguishing the final value as either a Left (result from short-circuiting)
or a Right (final value).  And EitherT can already do that, it just lacks a
convenience function to make it easier (i.e, not having to write lots of
nested if statements).

--

--
John Wiegley
FP Complete                         Haskell tools, training and consulting

_______________________________________________
```
23 Jan 2013 07:16

```>>>>> John Wiegley <johnw <at> fpcomplete.com> writes:

> And EitherT can already do that, it just lacks a convenience function to
> make it easier (i.e, not having to write lots of nested if statements).

Never mind, when/unless + left work just fine for this.

--

--
John Wiegley
FP Complete                         Haskell tools, training and consulting
```
23 Jan 2013 08:10

```>>>>> John Wiegley <johnw <at> fpcomplete.com> writes:

> Never mind, when/unless + left work just fine for this.

You know, it's been a humorous day.

First ekmett showed that I can't make a sane Monad instance for AndM or OrM.

Then I discovered I can't make a reasonable Monoid (no mempty, given only
'toBool'), so I dropped down to a Semigroup.  Further, my combinators for
EitherT can be implemented using just 'when' and 'left' to provide the
short-circuiting.

Already I had very little code left, until he showed me the Applicative
instance for Either, plus a little trick:

>>> Right 1 *> Right 2 *> Left 2 *> Right 5
Left 2              -- same functionality as my And semigroup

>>> let Left x |> y = y; x |> _ = x in Left 1 |> Right 2 |> Right 3
Right 2            -- same functionality as my Or semigroup

And poof, all my code just disappeared...

--

--
John Wiegley
FP Complete                         Haskell tools, training and consulting
```
23 Jan 2013 08:18

```John Wiegley <johnw <at> fpcomplete.com> wrote:

> And poof, all my code just disappeared...

Greets,
Ertugrul

--

--
Not to be or to be and (not to be or to be and (not to be or to be and
(not to be or to be and ... that is the list monad.
```
```_______________________________________________
```
23 Jan 2013 09:00

If we step back, I think the lesson here is that Haskell libraries exist, but the concepts are far enough from what you expect to exist given background knowledge from another programming language.

So what is actually needed is not monad-bool, but the equivalent documentation that makes a programmer which is not an expert in Haskell connect the dots like you did today.

Alexander

On Wed, Jan 23, 2013 at 8:10 AM, John Wiegley wrote:
>>>>> John Wiegley <johnw <at> fpcomplete.com> writes:

> Never mind, when/unless + left work just fine for this.

You know, it's been a humorous day.

First ekmett showed that I can't make a sane Monad instance for AndM or OrM.

Then I discovered I can't make a reasonable Monoid (no mempty, given only
'toBool'), so I dropped down to a Semigroup.  Further, my combinators for
EitherT can be implemented using just 'when' and 'left' to provide the
short-circuiting.

Already I had very little code left, until he showed me the Applicative
instance for Either, plus a little trick:

>>> Right 1 *> Right 2 *> Left 2 *> Right 5
Left 2              -- same functionality as my And semigroup

>>> let Left x |> y = y; x |> _ = x in Left 1 |> Right 2 |> Right 3
Right 2            -- same functionality as my Or semigroup

And poof, all my code just disappeared...

--
John Wiegley
FP Complete                         Haskell tools, training and consulting

_______________________________________________

```_______________________________________________
```
23 Jan 2013 22:14

2013/1/23 John Wiegley
>>>>> John Wiegley <johnw <at> fpcomplete.com> writes:

> Never mind, when/unless + left work just fine for this.

You know, it's been a humorous day.
...

Don't take it so hard. Trying to reinvent something is always a great exercise and makes you really understand the problem. And it can have interesting results too. One of my university professors once heard about some concept, but didn't know the details. He tried to derive the concept himself, and he actually invented something different, new and very useful.

...

>>> let Left x |> y = y; x |> _ = x in Left 1 |> Right 2 |> Right 3
Right 2            -- same functionality as my Or semigroup

This strongly reminds me of `mplus` of `Maybe`. The problem is we cannot define a generic instance `MonadPlus Either` because we cannot define `mzero` (but if we restrict the left type, we can achieve this, like in "instance Error e => MonadPlus (Either e)").

Another possibility how to capture this "Or" behavior is `MonadError`. You could define |> for any instance of `MonadError`, including Either (currently with some restrictions):

(|>) :: MonadError e m => m a -> m a -> m a
x |> y = x `catchError` (const y)

Best regards,
Petr Pudlak

```_______________________________________________
```
24 Jan 2013 00:57

```>>>>> Petr P <petr.mvd <at> gmail.com> writes:

> Don't take it so hard. Trying to reinvent something is always a great
> exercise and makes you really understand the problem. And it can have
> interesting results too. One of my university professors once heard about
> some concept, but didn't know the details. He tried to derive the concept
> himself, and he actually invented something different, new and very useful.

Thank you very much to everyone for the encouragement, and especially to
Edward and Shachaf for the education on #haskell.  It will be hard to unlearn
a lesson like this one. :)  And I will certainly endeavor to make the most
valuable mistakes I can from here on, with the help of such a gracious
community. :)

Yours,
--

--
John Wiegley
FP Complete                         Haskell tools, training and consulting
```
23 Jan 2013 07:02

```>>>>> Roman Cheplyaka <roma <at> ro-che.info> writes:

> - what do you need unsafeCoerce for?

Ok, after much discussion with edwardk and shachaf, I came to realize a few
things:

1. The functionality of my two monads 'AndM' and 'OrR' can be boiled down to
two helper functions inside EitherT:

returnIf :: Monad m => Bool -> e -> EitherT e m ()
returnIf p a = if p then left a else right ()

returnUnless :: Monad m => Bool -> e -> EitherT e m ()
returnUnless p = returnIf (not p)

These let you short-circuit monadic computations, returning the
short-circuiting value as a Left; or as a Right if it reaches the end.

2. The 'shortcircuit' library already provides short-circuiting variants of
&& and || that work just like Python's and Ruby's.  In fact, I think I'll
talk to aristid about merging my Monoid definitions into that library.

Here are the updated docs:

http://ftp.newartisans.com/pub/monoid-bool/Data-Monoid-Bool.html

I'll ask Ross Paterson to deprecate monad-bool.  And in future, I'll seek

--

--
John Wiegley
FP Complete                         Haskell tools, training and consulting
```
23 Jan 2013 11:28

Em 23/01/2013 04:03, "John Wiegley" <johnw <at> fpcomplete.com> escreveu:
> I'll ask Ross Paterson to deprecate monad-bool.  And in future, I'll seek

Release early and release often, don't worry about asking the mailing list beforehand (unless you want to, of course).

Cheers,

--
Felipe.

```_______________________________________________
```
23 Jan 2013 17:01

On Wed, Jan 23, 2013 at 5:28 PM, Felipe Almeida Lessa wrote:

don't worry about asking the mailing list beforehand (unless you want to, of course).

Seconded!

Just a cursory sweep of this thread reveals so much learning and discovery taking place that would be utterly lost should a self-censoring arrant pedantry take hold.

Props to John for motivating the use case (on haskell-cafe, no less!) for monad-bool that sparked this discussion in the first place. Half of the time, I can't tell what problem a package is trying to solve. I look forward to seeing more of his contributions.

-- Kim-Ee
```_______________________________________________
```
24 Jan 2013 00:23

```On 1/23/13 3:00 AM, Alexander Kjeldaas wrote:
> If we step back, I think the lesson here is that Haskell libraries exist,
> but the concepts are far enough from what you expect to exist given
> background knowledge from another programming language.
>
> So what is actually needed is not monad-bool, but the equivalent
> documentation that makes a programmer which is not an expert in Haskell
> connect the dots like you did today.

Definitely.

We could even set up NotOnHackage: a "package" repository just like
Hackage, except the packages are just documentation on why there is no
such package. Implementation-wise it's just a wiki; but the idea is about
how to organize the wiki. NotOnHackage should be organized and searchable
similar to Hackage itself, so that people can look there when nothing
looks promising on Hackage.

--

--
Live well,
~wren
```
24 Jan 2013 00:27

Couldn't this be actually on hackage, so one search turns up what you want?

On Jan 23, 2013 3:24 PM, "wren ng thornton" <wren <at> freegeek.org> wrote:
On 1/23/13 3:00 AM, Alexander Kjeldaas wrote:
> If we step back, I think the lesson here is that Haskell libraries exist,
> but the concepts are far enough from what you expect to exist given
> background knowledge from another programming language.
>
> So what is actually needed is not monad-bool, but the equivalent
> documentation that makes a programmer which is not an expert in Haskell
> connect the dots like you did today.

Definitely.

We could even set up NotOnHackage: a "package" repository just like
Hackage, except the packages are just documentation on why there is no
such package. Implementation-wise it's just a wiki; but the idea is about
how to organize the wiki. NotOnHackage should be organized and searchable
similar to Hackage itself, so that people can look there when nothing
looks promising on Hackage.

--
Live well,
~wren

_______________________________________________
```_______________________________________________
```
24 Jan 2013 07:40

```David Thomas <davidleothomas <at> gmail.com> wrote:

> > We could even set up NotOnHackage: a "package" repository just like
> > Hackage, except the packages are just documentation on why there is
> > no such package. Implementation-wise it's just a wiki; but the idea
> > is about how to organize the wiki. NotOnHackage should be organized
> > and searchable similar to Hackage itself, so that people can look
> > there when nothing looks promising on Hackage.
>
> Couldn't this be actually on hackage, so one search turns up what you
> want?

Yes.  There is no reason to put up a second Hackage for that one.
Without changing anything in the current system, packages can just
update their categories, so that they will be displayed below "Defunct"
or something like that.  This is fine, as only the categories of the

If you think this is a good idea, I will start with some of my
packages. =)

Greets,
Ertugrul

--

--
Not to be or to be and (not to be or to be and (not to be or to be and
(not to be or to be and ... that is the list monad.
```
```_______________________________________________
```
26 Jan 2013 00:23

```On 1/24/13 1:40 AM, Ertugrul Söylemez wrote:
> David Thomas <davidleothomas <at> gmail.com> wrote:
>
>>> We could even set up NotOnHackage: a "package" repository just like
>>> Hackage, except the packages are just documentation on why there is
>>> no such package. Implementation-wise it's just a wiki; but the idea
>>> is about how to organize the wiki. NotOnHackage should be organized
>>> and searchable similar to Hackage itself, so that people can look
>>> there when nothing looks promising on Hackage.
>>
>> Couldn't this be actually on hackage, so one search turns up what you
>> want?
>
> Yes.  There is no reason to put up a second Hackage for that one.
> Without changing anything in the current system, packages can just
> update their categories, so that they will be displayed below "Defunct"
> or something like that.  This is fine, as only the categories of the
>
> If you think this is a good idea, I will start with some of my
> packages. =)

We've had package deprecation for a while, so the big trick IMO is the
documentation. Good descriptions of why the package is defunct and
suggestions on how people can do things better.

If we're going to do it on Hackage itself, I think the big question is
one of style: should the documentation be all in the cabal file (i.e.,
on the package description page, with no modules in the package); or
should we put the documentation into modules?

--

--
Live well,
~wren
```
26 Jan 2013 00:32

I think it needs to be both places.  I know when I'm searching, I often just go to google with "site:hackage.haskell.org inurl:latest"  I would be likely to miss it if it were just in the cabal file (although in the modules it could be as simple as a note saying "this is defunct - view the main page for an explanation of why).  Alternatively, if there is much reasoning specific to a particular module it could certainly go there, while the cabal gets the overview...

On Fri, Jan 25, 2013 at 3:23 PM, wren ng thornton wrote:
On 1/24/13 1:40 AM, Ertugrul Söylemez wrote:
David Thomas <davidleothomas <at> gmail.com> wrote:

We could even set up NotOnHackage: a "package" repository just like
Hackage, except the packages are just documentation on why there is
no such package. Implementation-wise it's just a wiki; but the idea
is about how to organize the wiki. NotOnHackage should be organized
and searchable similar to Hackage itself, so that people can look
there when nothing looks promising on Hackage.

Couldn't this be actually on hackage, so one search turns up what you
want?

Yes.  There is no reason to put up a second Hackage for that one.
Without changing anything in the current system, packages can just
update their categories, so that they will be displayed below "Defunct"
or something like that.  This is fine, as only the categories of the

If you think this is a good idea, I will start with some of my
packages. =)

We've had package deprecation for a while, so the big trick IMO is the documentation. Good descriptions of why the package is defunct and suggestions on how people can do things better.

If we're going to do it on Hackage itself, I think the big question is one of style: should the documentation be all in the cabal file (i.e., on the package description page, with no modules in the package); or should we put the documentation into modules?

--
Live well,
~wren

_______________________________________________

```_______________________________________________
```
26 Jan 2013 07:00

A brief stylistic note: to me, defunct has a connotation similar to that of deprecated, just stronger; meaning, it implies something closer to "NoLongerOnHackage" rather than wren's more general "NotOnHackage." In this case, the distinction is moot, because the code did happen to exist on Hackage, but I imagine there are cases one might want to warn against without this condition being true.

On Fri, Jan 25, 2013 at 6:32 PM, David Thomas wrote:
I think it needs to be both places.  I know when I'm searching, I often just go to google with "site:hackage.haskell.org inurl:latest"  I would be likely to miss it if it were just in the cabal file (although in the modules it could be as simple as a note saying "this is defunct - view the main page for an explanation of why).  Alternatively, if there is much reasoning specific to a particular module it could certainly go there, while the cabal gets the overview...

On Fri, Jan 25, 2013 at 3:23 PM, wren ng thornton wrote:
On 1/24/13 1:40 AM, Ertugrul Söylemez wrote:
David Thomas <davidleothomas <at> gmail.com> wrote:

We could even set up NotOnHackage: a "package" repository just like
Hackage, except the packages are just documentation on why there is
no such package. Implementation-wise it's just a wiki; but the idea
is about how to organize the wiki. NotOnHackage should be organized
and searchable similar to Hackage itself, so that people can look
there when nothing looks promising on Hackage.

Couldn't this be actually on hackage, so one search turns up what you
want?

Yes.  There is no reason to put up a second Hackage for that one.
Without changing anything in the current system, packages can just
update their categories, so that they will be displayed below "Defunct"
or something like that.  This is fine, as only the categories of the

If you think this is a good idea, I will start with some of my
packages. =)

We've had package deprecation for a while, so the big trick IMO is the documentation. Good descriptions of why the package is defunct and suggestions on how people can do things better.

If we're going to do it on Hackage itself, I think the big question is one of style: should the documentation be all in the cabal file (i.e., on the package description page, with no modules in the package); or should we put the documentation into modules?

--
Live well,
~wren

_______________________________________________

_______________________________________________

```_______________________________________________
```
26 Jan 2013 10:56

```wren ng thornton <wren <at> freegeek.org> wrote:

> > Yes.  There is no reason to put up a second Hackage for that one.
> > Without changing anything in the current system, packages can just
> > update their categories, so that they will be displayed below
> > "Defunct" or something like that.  This is fine, as only the
> >
> > If you think this is a good idea, I will start with some of my
> > packages. =)
>
> We've had package deprecation for a while, so the big trick IMO is the
> documentation. Good descriptions of why the package is defunct and
> suggestions on how people can do things better.
>
> If we're going to do it on Hackage itself, I think the big question is
> one of style: should the documentation be all in the cabal file (i.e.,
> on the package description page, with no modules in the package); or
> should we put the documentation into modules?

I think the package should be included in full, and the package
documentation should clarify why the package shouldn't be used.  The
idea is that people can still download the code and see how not to do
it.  It also helps to keep legacy code working, because "bad idea"
doesn't necessarily mean, "you could die if you use this".

You might go as far as implementing special support for this in the
cabal-install tool in the form of a flag like --allow-defunct.

Greets,
Ertugrul

--

--
Not to be or to be and (not to be or to be and (not to be or to be and
(not to be or to be and ... that is the list monad.
```
```_______________________________________________
```
24 Jan 2013 00:33

On Thu, Jan 24, 2013 at 6:23 AM, wren ng thornton wrote:

NotOnHackage: a "package" repository just like
Hackage, except the packages are just documentation on why there is no
such package.

Love the idea! It'll make us even more unique among other PLs and even more ways to be smug:

"A bigger set of libraries? So what? Haskell's the only one with a /negative/ repo. Eat your heart out, Python!" ;)

-- Kim-Ee
```_______________________________________________