All-fail case in asum

Hello I want to define some parser such way: myParser = tryA <|> tryB <|> fail "input must be either A or B" It works. But then I want to rewrite it with asum: myParser = asum [tryA, tryB, fail "must be A or B"] It works, but the wrong way. Instead of my error it writes "empty". Just "empty". It is so because in base library asum = foldr (<|>) empty What if it was defined asum [] = empty asum [x:xs] = x <|> asum xs It would help me with my parser. But what can this break? Why isn't this done yet? -- Yuriy Syrovetskiy, http://cblp.su

On Fri, Jun 10, 2016 at 05:37:41PM +0300, Юрий Сыровецкий (Yuriy Syrovetskiy) wrote:
It is so because in base library
asum = foldr (<|>) empty
What if it was defined
asum [] = empty asum [x:xs] = x <|> asum xs
Those are the same (assuming you mean (x:xs) instead of [x:xs]). Tom

Add a pattern match for the single-element list to stop it from hitting the empty list base case. asum [] = empty asum [x] = x asum (x:xs) = x <|> asum xs On Friday, June 10, 2016, Tom Ellis < tom-lists-haskell-cafe-2013@jaguarpaw.co.uk> wrote:
On Fri, Jun 10, 2016 at 05:37:41PM +0300, Юрий Сыровецкий (Yuriy Syrovetskiy) wrote:
It is so because in base library
asum = foldr (<|>) empty
What if it was defined
asum [] = empty asum [x:xs] = x <|> asum xs
Those are the same (assuming you mean (x:xs) instead of [x:xs]).
Tom _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org javascript:; http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
-- -- Dan Burton

Disregarding is `asum` should be changed, perhaps you could fix your
issue by doing:
myParser = asum [tryA, tryB] <|> fail "input must be either A or B"
Erik
On 10 June 2016 at 16:37, Юрий Сыровецкий (Yuriy Syrovetskiy)
Hello
I want to define some parser such way:
myParser = tryA <|> tryB <|> fail "input must be either A or B"
It works. But then I want to rewrite it with asum:
myParser = asum [tryA, tryB, fail "must be A or B"]
It works, but the wrong way. Instead of my error it writes "empty". Just "empty".
It is so because in base library
asum = foldr (<|>) empty
What if it was defined
asum [] = empty asum [x:xs] = x <|> asum xs
It would help me with my parser. But what can this break? Why isn't this done yet?
-- Yuriy Syrovetskiy, http://cblp.su _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

Of course, but I want the *perfect* solution.
I think, this Parser type is not perfectly monoidal, so in general asum and
(<|>) are not interchangeable.
On 10 Jun 2016 19:51, "Erik Hesselink"
Disregarding is `asum` should be changed, perhaps you could fix your issue by doing:
myParser = asum [tryA, tryB] <|> fail "input must be either A or B"
Erik
On 10 June 2016 at 16:37, Юрий Сыровецкий (Yuriy Syrovetskiy)
wrote: Hello
I want to define some parser such way:
myParser = tryA <|> tryB <|> fail "input must be either A or B"
It works. But then I want to rewrite it with asum:
myParser = asum [tryA, tryB, fail "must be A or B"]
It works, but the wrong way. Instead of my error it writes "empty". Just "empty".
It is so because in base library
asum = foldr (<|>) empty
What if it was defined
asum [] = empty asum [x:xs] = x <|> asum xs
It would help me with my parser. But what can this break? Why isn't this done yet?
-- Yuriy Syrovetskiy, http://cblp.su _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

On Fri, Jun 10, 2016 at 07:56:04PM +0300, Юрий Сыровецкий (Yuriy Syrovetskiy) wrote:
I think, this Parser type is not perfectly monoidal, so in general asum and (<|>) are not interchangeable.
Please can you post an example showing that? I am unable to replicate this behaviour. ghci> import Text.ParserCombinators.Parsec ghci> import Data.Foldable ghci> let ar = asum [space, space, fail "My fail"] :: Parser Char ghci> runParser ar () "" "x" Left (line 1, column 1): unexpected "x" expecting space My fail It seems that the custom fail is indeed picked up. No hint of "error" here. Tom

If you aren’t scared of the dependencies: semigroupoids has asum1 (yet it’s easy to write yourself) https://s3.amazonaws.com/haddock.stackage.org/lts-6.2/semigroupoids-5.0.1/Da... λ Prelude Data.Semigroup.Foldable Data.List.NonEmpty > asum1 ([Right 1, Right 2, Left "error"] :: NonEmpty (Either String Int)) Right 1 λ Prelude Data.Semigroup.Foldable Data.List.NonEmpty > asum1 ([Left "error"] :: NonEmpty (Either String Int)) Left "error" - Oleg
On 10 Jun 2016, at 17:37, Юрий Сыровецкий (Yuriy Syrovetskiy)
wrote: Hello
I want to define some parser such way:
myParser = tryA <|> tryB <|> fail "input must be either A or B"
It works. But then I want to rewrite it with asum:
myParser = asum [tryA, tryB, fail "must be A or B"]
It works, but the wrong way. Instead of my error it writes "empty". Just "empty".
It is so because in base library
asum = foldr (<|>) empty
What if it was defined
asum [] = empty asum [x:xs] = x <|> asum xs
It would help me with my parser. But what can this break? Why isn't this done yet?
-- Yuriy Syrovetskiy, http://cblp.su _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

λ> :show imports
import Prelude -- implicit
import Data.Aeson.Types
import Data.Foldable
import Control.Applicative
λ> parse (\v -> withObject "Object" (\_ -> pure "OK") v <|> fail
"Expected object") Null
Error "Expected object"
λ> parse (\v -> asum [withObject "Object" (\_ -> pure "OK") v, fail
"Expected object"]) Null
Error "empty"
Maybe instance Alternative Parser should be changed to ignore "empty"?
2016-06-10 20:01 GMT+03:00 Oleg Grenrus
If you aren’t scared of the dependencies: semigroupoids has asum1 (yet it’s easy to write yourself)
https://s3.amazonaws.com/haddock.stackage.org/lts-6.2/semigroupoids-5.0.1/Da...
λ Prelude Data.Semigroup.Foldable Data.List.NonEmpty > asum1 ([Right 1, Right 2, Left "error"] :: NonEmpty (Either String Int)) Right 1 λ Prelude Data.Semigroup.Foldable Data.List.NonEmpty > asum1 ([Left "error"] :: NonEmpty (Either String Int)) Left "error"
- Oleg
On 10 Jun 2016, at 17:37, Юрий Сыровецкий (Yuriy Syrovetskiy)
wrote: Hello
I want to define some parser such way:
myParser = tryA <|> tryB <|> fail "input must be either A or B"
It works. But then I want to rewrite it with asum:
myParser = asum [tryA, tryB, fail "must be A or B"]
It works, but the wrong way. Instead of my error it writes "empty". Just "empty".
It is so because in base library
asum = foldr (<|>) empty
What if it was defined
asum [] = empty asum [x:xs] = x <|> asum xs
It would help me with my parser. But what can this break? Why isn't this done yet?
-- Yuriy Syrovetskiy, http://cblp.su _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
-- Yuriy Syrovetskiy, http://cblp.su

OK, so you're using attoparsec (through aeson). That's valuable information would have been useful to include in your initial email. After a bit of experimenting and reading the docs, I think the problem is that attoparsec's Alternative instance isn't completely correct.
From the docs, Alternative is supposed to be "a monoid on applicative functors". The Monoid laws say, among other things, that `mappend x mempty = x`. For Applicative, this would mean `x <|> empty = x`. However, in attoparsec:
λ parse (fail "boom" <|> empty) "hello"
Fail "hello" [] "Failed reading: empty"
In parsec, on the other hand:
λ parse (fail "boom" <|> empty) "" "hello"
Left (line 1, column 1):
boom
So I don't think changing Applicative or asum is the way to go here.
Erik
On 11 June 2016 at 07:15, Юрий Сыровецкий (Yuriy Syrovetskiy)
λ> :show imports import Prelude -- implicit import Data.Aeson.Types import Data.Foldable import Control.Applicative λ> parse (\v -> withObject "Object" (\_ -> pure "OK") v <|> fail "Expected object") Null Error "Expected object" λ> parse (\v -> asum [withObject "Object" (\_ -> pure "OK") v, fail "Expected object"]) Null Error "empty"
Maybe instance Alternative Parser should be changed to ignore "empty"?
2016-06-10 20:01 GMT+03:00 Oleg Grenrus
: If you aren’t scared of the dependencies: semigroupoids has asum1 (yet it’s easy to write yourself)
https://s3.amazonaws.com/haddock.stackage.org/lts-6.2/semigroupoids-5.0.1/Da...
λ Prelude Data.Semigroup.Foldable Data.List.NonEmpty > asum1 ([Right 1, Right 2, Left "error"] :: NonEmpty (Either String Int)) Right 1 λ Prelude Data.Semigroup.Foldable Data.List.NonEmpty > asum1 ([Left "error"] :: NonEmpty (Either String Int)) Left "error"
- Oleg
On 10 Jun 2016, at 17:37, Юрий Сыровецкий (Yuriy Syrovetskiy)
wrote: Hello
I want to define some parser such way:
myParser = tryA <|> tryB <|> fail "input must be either A or B"
It works. But then I want to rewrite it with asum:
myParser = asum [tryA, tryB, fail "must be A or B"]
It works, but the wrong way. Instead of my error it writes "empty". Just "empty".
It is so because in base library
asum = foldr (<|>) empty
What if it was defined
asum [] = empty asum [x:xs] = x <|> asum xs
It would help me with my parser. But what can this break? Why isn't this done yet?
-- Yuriy Syrovetskiy, http://cblp.su _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
-- Yuriy Syrovetskiy, http://cblp.su _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

So should we consider it a bug in attoparsec? And should somebody fix it?
On 11 Jun 2016 10:04, "Erik Hesselink"
OK, so you're using attoparsec (through aeson). That's valuable information would have been useful to include in your initial email.
After a bit of experimenting and reading the docs, I think the problem is that attoparsec's Alternative instance isn't completely correct. From the docs, Alternative is supposed to be "a monoid on applicative functors". The Monoid laws say, among other things, that `mappend x mempty = x`. For Applicative, this would mean `x <|> empty = x`. However, in attoparsec:
λ parse (fail "boom" <|> empty) "hello" Fail "hello" [] "Failed reading: empty"
In parsec, on the other hand:
λ parse (fail "boom" <|> empty) "" "hello" Left (line 1, column 1): boom
So I don't think changing Applicative or asum is the way to go here.
Erik
On 11 June 2016 at 07:15, Юрий Сыровецкий (Yuriy Syrovetskiy)
wrote: λ> :show imports import Prelude -- implicit import Data.Aeson.Types import Data.Foldable import Control.Applicative λ> parse (\v -> withObject "Object" (\_ -> pure "OK") v <|> fail "Expected object") Null Error "Expected object" λ> parse (\v -> asum [withObject "Object" (\_ -> pure "OK") v, fail "Expected object"]) Null Error "empty"
Maybe instance Alternative Parser should be changed to ignore "empty"?
2016-06-10 20:01 GMT+03:00 Oleg Grenrus
: If you aren’t scared of the dependencies: semigroupoids has asum1 (yet it’s easy to write yourself)
https://s3.amazonaws.com/haddock.stackage.org/lts-6.2/semigroupoids-5.0.1/Da...
λ Prelude Data.Semigroup.Foldable Data.List.NonEmpty > asum1 ([Right 1,
Right 2, Left "error"] :: NonEmpty (Either String Int))
Right 1 λ Prelude Data.Semigroup.Foldable Data.List.NonEmpty > asum1 ([Left "error"] :: NonEmpty (Either String Int)) Left "error"
- Oleg
On 10 Jun 2016, at 17:37, Юрий Сыровецкий (Yuriy Syrovetskiy) < cblp@cblp.su> wrote:
Hello
I want to define some parser such way:
myParser = tryA <|> tryB <|> fail "input must be either A or B"
It works. But then I want to rewrite it with asum:
myParser = asum [tryA, tryB, fail "must be A or B"]
It works, but the wrong way. Instead of my error it writes "empty". Just "empty".
It is so because in base library
asum = foldr (<|>) empty
What if it was defined
asum [] = empty asum [x:xs] = x <|> asum xs
It would help me with my parser. But what can this break? Why isn't this done yet?
-- Yuriy Syrovetskiy, http://cblp.su _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
-- Yuriy Syrovetskiy, http://cblp.su _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

It depends on definition of equivalence for your Functor. When proving Alternative laws for artoparsec's Parser all errors are treated as equivalent: so no problem. Also attoparsec concentrates on the speed, not error reporting: Parsec parsers can produce more helpful error messages than attoparsec parsers. This is a matter of focus: attoparsec avoids the extra book-keeping in favour of higher performance. Sent from my iPhone
On 11 Jun 2016, at 10:15, Юрий Сыровецкий (Yuriy Syrovetskiy)
wrote: So should we consider it a bug in attoparsec? And should somebody fix it?
On 11 Jun 2016 10:04, "Erik Hesselink"
wrote: OK, so you're using attoparsec (through aeson). That's valuable information would have been useful to include in your initial email. After a bit of experimenting and reading the docs, I think the problem is that attoparsec's Alternative instance isn't completely correct. From the docs, Alternative is supposed to be "a monoid on applicative functors". The Monoid laws say, among other things, that `mappend x mempty = x`. For Applicative, this would mean `x <|> empty = x`. However, in attoparsec:
λ parse (fail "boom" <|> empty) "hello" Fail "hello" [] "Failed reading: empty"
In parsec, on the other hand:
λ parse (fail "boom" <|> empty) "" "hello" Left (line 1, column 1): boom
So I don't think changing Applicative or asum is the way to go here.
Erik
On 11 June 2016 at 07:15, Юрий Сыровецкий (Yuriy Syrovetskiy)
wrote: λ> :show imports import Prelude -- implicit import Data.Aeson.Types import Data.Foldable import Control.Applicative λ> parse (\v -> withObject "Object" (\_ -> pure "OK") v <|> fail "Expected object") Null Error "Expected object" λ> parse (\v -> asum [withObject "Object" (\_ -> pure "OK") v, fail "Expected object"]) Null Error "empty"
Maybe instance Alternative Parser should be changed to ignore "empty"?
2016-06-10 20:01 GMT+03:00 Oleg Grenrus
: If you aren’t scared of the dependencies: semigroupoids has asum1 (yet it’s easy to write yourself)
https://s3.amazonaws.com/haddock.stackage.org/lts-6.2/semigroupoids-5.0.1/Da...
λ Prelude Data.Semigroup.Foldable Data.List.NonEmpty > asum1 ([Right 1, Right 2, Left "error"] :: NonEmpty (Either String Int)) Right 1 λ Prelude Data.Semigroup.Foldable Data.List.NonEmpty > asum1 ([Left "error"] :: NonEmpty (Either String Int)) Left "error"
- Oleg
On 10 Jun 2016, at 17:37, Юрий Сыровецкий (Yuriy Syrovetskiy)
wrote: Hello
I want to define some parser such way:
myParser = tryA <|> tryB <|> fail "input must be either A or B"
It works. But then I want to rewrite it with asum:
myParser = asum [tryA, tryB, fail "must be A or B"]
It works, but the wrong way. Instead of my error it writes "empty". Just "empty".
It is so because in base library
asum = foldr (<|>) empty
What if it was defined
asum [] = empty asum [x:xs] = x <|> asum xs
It would help me with my parser. But what can this break? Why isn't this done yet?
-- Yuriy Syrovetskiy, http://cblp.su _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
-- Yuriy Syrovetskiy, http://cblp.su _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
participants (5)
-
Dan Burton
-
Erik Hesselink
-
Oleg Grenrus
-
Tom Ellis
-
Юрий Сыровецкий (Yuriy Syrovetskiy)