
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