Sterling Clover s.clover at gmail.com
Fri Jul 10 17:41:58 EDT 2009

```On Jul 10, 2009, at 4:35 AM, Wolfgang Jeltsch wrote:
>
> I fear that this instance doesn’t satisfy required laws. As far as
> I know, the
> following equalities should hold:
>
>     (*>) = (>>)
>
>     f *> empty = empty
>
>     empty <|> g = g
>
> This implies the following:
>
>     (f >> empty) <|> g = g
>
> But this wouldn’t hold with your instance. (f >> empty) <|> g would
> cause the
> side effects of f and of g, while g would (obviously) only cause
> the side
> effects of g.

I think the third equality you provide is too strong (which isn't to
say that it might not be the law that people have documented and
expect). Lots of useful alternative instances fail it, not least any
parser combinator library (such as Parsec) without automatic
backtracking.

A more realistic law would perhaps be:

> (f *> empty) <|> g = f *> g

Additionally, the second equality you provide is just wrong.

f *> empty = empty is no more true than f *> g = g, which is no more
true than f >> g = g, which is obviously not true at all, as
putStrLn "Hey There" >> return () obviously /= return ()

Cheers,
Sterl
```