PROPOSAL: Some more 'Applicative' combinators

11 messages
Open this post in threaded view
|

PROPOSAL: Some more 'Applicative' combinators

 Hello, I propose that we add the following combinators to the 'Control.Applicative' module: skipMany   :: (Alternative f) => f a -> f () skipMany p  = skipSome p <|> pure () skipSome   :: (Alternative f) => f a -> f () skipSome p  = p *> skipMany p endBy      :: (Alternative f) => f a -> f b -> f [a] endBy p s   = many (p <* s) endBy1     :: (Alternative f) => f a -> f b -> f [a] endBy1 p s  = some (p <* s) sepBy      :: (Alternative f) => f a -> f v -> f [a] sepBy p s   = sepBy1 p s <|> pure [] sepBy1     :: (Alternative f) => f a -> f v -> f [a] sepBy1 p s  = (:) <\$> p <*> many (s *> p) Any objections?  Deadline for discussion is 2 weeks from now, which would be the 20th of Jan. -Iavor _______________________________________________ Libraries mailing list [hidden email] http://www.haskell.org/mailman/listinfo/libraries
Open this post in threaded view
|

Re: PROPOSAL: Some more 'Applicative' combinators

 Can you show some code fragments demonstrating how the combinators are used?  I find it easier to understand the underlying concepts when I have not only the signature and implementation but an example of a typical use.  It doesn't have to be working code, and it might even be pseudo code.  (I'm not sure whether other Haskell folks feel the same way.) On Sun, 6 Jan 2008 13:35:41 -0800 "Iavor Diatchki" <[hidden email]> wrote: > Hello, > I propose that we add the following combinators to the > 'Control.Applicative' module: > > skipMany   :: (Alternative f) => f a -> f () > skipMany p  = skipSome p <|> pure () > > skipSome   :: (Alternative f) => f a -> f () > skipSome p  = p *> skipMany p > > endBy      :: (Alternative f) => f a -> f b -> f [a] > endBy p s   = many (p <* s) > > endBy1     :: (Alternative f) => f a -> f b -> f [a] > endBy1 p s  = some (p <* s) > > sepBy      :: (Alternative f) => f a -> f v -> f [a] > sepBy p s   = sepBy1 p s <|> pure [] > > sepBy1     :: (Alternative f) => f a -> f v -> f [a] > sepBy1 p s  = (:) <\$> p <*> many (s *> p) > > > Any objections?  Deadline for discussion is 2 weeks from now, which > would be the 20th of Jan. > > -Iavor > _______________________________________________ > Libraries mailing list > [hidden email] > http://www.haskell.org/mailman/listinfo/libraries> -- Seth Kurtzberg <[hidden email]> Hardware/Software/Driver Engineering _______________________________________________ Libraries mailing list [hidden email] http://www.haskell.org/mailman/listinfo/libraries
Open this post in threaded view
|

Re: PROPOSAL: Some more 'Applicative' combinators

 Hello, Sorry, I should have mentioned the origin of the combinators.  These are (generalizations of) standard parser combinators, so think of "f a" in the type as a parser that can construct values of type "a". With this in mind, it should be more obvious what these combinators are used for.   For example: > p `sepBy` sep is a parser that will return 0 or more occurances of 'p' separated by 'sep'.  Many (all?) parser combinator libraries provide these functions, so having the generic 'Alternative' interface makes it easier to write parser that can work with different libraries. -Iavor On Jan 6, 2008 3:34 PM, Seth Kurtzberg <[hidden email]> wrote: > Can you show some code fragments demonstrating how the combinators are used?  I find it easier to understand the underlying concepts when I have not only the signature and implementation but an example of a typical use.  It doesn't have to be working code, and it might even be pseudo code.  (I'm not sure whether other Haskell folks feel the same way.) > > > On Sun, 6 Jan 2008 13:35:41 -0800 > "Iavor Diatchki" <[hidden email]> wrote: > > > Hello, > > I propose that we add the following combinators to the > > 'Control.Applicative' module: > > > > skipMany   :: (Alternative f) => f a -> f () > > skipMany p  = skipSome p <|> pure () > > > > skipSome   :: (Alternative f) => f a -> f () > > skipSome p  = p *> skipMany p > > > > endBy      :: (Alternative f) => f a -> f b -> f [a] > > endBy p s   = many (p <* s) > > > > endBy1     :: (Alternative f) => f a -> f b -> f [a] > > endBy1 p s  = some (p <* s) > > > > sepBy      :: (Alternative f) => f a -> f v -> f [a] > > sepBy p s   = sepBy1 p s <|> pure [] > > > > sepBy1     :: (Alternative f) => f a -> f v -> f [a] > > sepBy1 p s  = (:) <\$> p <*> many (s *> p) > > > > > > Any objections?  Deadline for discussion is 2 weeks from now, which > > would be the 20th of Jan. > > > > -Iavor > > _______________________________________________ > > Libraries mailing list > > [hidden email] > > http://www.haskell.org/mailman/listinfo/libraries> > > > > -- > Seth Kurtzberg <[hidden email]> > Hardware/Software/Driver Engineering > _______________________________________________ Libraries mailing list [hidden email] http://www.haskell.org/mailman/listinfo/libraries
Open this post in threaded view
|

Re: PROPOSAL: Some more 'Applicative' combinators

 In reply to this post by Iavor Diatchki Iavor Diatchki wrote: > I propose that we add the following combinators to the > 'Control.Applicative' module: While applicative functors are good for this task, it would be a shame if the innocent reader of haddocks were to acquire the impression that parsing was all they were for. Why not make the task specificity clearer, with a separate Control.Applicative.Parsing module?
Open this post in threaded view
|

Re: PROPOSAL: Some more 'Applicative' combinators

 Hello, On Jan 6, 2008 9:20 PM, Bryan O'Sullivan <[hidden email]> wrote: > While applicative functors are good for this task, it would be a shame > if the innocent reader of haddocks were to acquire the impression that > parsing was all they were for. :-) oh, come on!  I was just giving an example of what these combinators may be used for.   They are not any more related to parsing than say, 'many', 'some', or 'empty' and '(<|>)'---they provide just a few  more useful control structures. > Why not make the task specificity clearer, with a separate > Control.Applicative.Parsing module? Now _this_ would definitely suggest that they are only good for parsing which would be misleading. -Iavor _______________________________________________ Libraries mailing list [hidden email] http://www.haskell.org/mailman/listinfo/libraries
Open this post in threaded view
|

Re: PROPOSAL: Some more 'Applicative' combinators

 iavor.diatchki: > Hello, > > On Jan 6, 2008 9:20 PM, Bryan O'Sullivan <[hidden email]> wrote: > > While applicative functors are good for this task, it would be a shame > > if the innocent reader of haddocks were to acquire the impression that > > parsing was all they were for. > > :-) oh, come on!  I was just giving an example of what these > combinators may be used for.   They are not any more related to > parsing than say, 'many', 'some', or 'empty' and '(<|>)'---they > provide just a few  more useful control structures. > > > Why not make the task specificity clearer, with a separate > > Control.Applicative.Parsing module? > > Now _this_ would definitely suggest that they are only good for > parsing which would be misleading. +1 for this proposal. Glue for combining parsers seems like a missing piece. Perhaps toss in an example in the docs? _______________________________________________ Libraries mailing list [hidden email] http://www.haskell.org/mailman/listinfo/libraries
Open this post in threaded view
|

Re: PROPOSAL: Some more 'Applicative' combinators

 In reply to this post by Iavor Diatchki Iavor wrote: > I propose that we add the following combinators to the > 'Control.Applicative' module: Here's a bunch, I've been using for quite some time now:    infixl 5 , , <, >    infixl 4 <\$\$>, <^>, <^, <^^>, , , <+>    infixl 3 <||>    infixl 2 `opt`    (<\$\$>)   :: (Applicative f) => f a -> (a -> b) -> f b    v <\$\$> f =  v <**> pure f    (<^>)   :: (Applicative f) => f (a -> b -> c) -> f b -> f (a -> c)    l <^> r =  flip <\$> l <*> r    (<^)   :: (Applicative f) => f (a -> b -> c) -> f d -> f (b -> a ->   c)    l <^ r =  flip <\$> l <* r    (<^^>)   :: (Applicative f) => f b -> f (a -> b -> c) -> f (a -> c)    l <^^> r =  l <**> (flip <\$> r)    ()   :: (Applicative f) => (a -> b -> c) -> f b -> f (a -> c)    f v =  flip f <\$> v    ( (a -> b -> c) -> f d -> f (b -> a -> c)    f )   :: (Applicative f) => f b -> (a -> b -> c) -> f (a -> c)    v f =  v <\$\$> flip f    (<+>)   :: (Applicative f) => f a -> f b -> f (a, b)    l <+> r =  (,) <\$> l <*> r    (<||>)   :: (Alternative f) => f a -> f b -> f (Either a b)    l <||> r =  Left <\$> l <|> Right <\$> r    ()   :: (Alternative f) => a -> f a -> f a    x v =  v <|> pure x    (), opt :: (Alternative f) => f a -> a -> f a    v x    =  v <|> pure x    opt         =  ()    (<)   :: (Alternative f) => f (a -> a) -> f a -> f a    l < r =  id l <*> r    (>)   :: (Alternative f) => f a -> f (a -> a) -> f a    l > r =  l <**> r id    packed       :: (Applicative f) => f a -> f b -> f c -> f c    packed l r v =  l *> v <* r    choice :: (Alternative f) => [f a] -> f a    choice =  foldr (<|>) empty    foldrMany        :: (Alternative f) => (a -> b -> b) -> b -> f a ->   f b    foldrMany op e v =  go      where        go = op <\$> v <*> go `opt` e    foldrSome        :: (Alternative f) => (a -> b -> b) -> b -> f a ->   f b    foldrSome op e v =  op <\$> v <*> go      where        go = op <\$> v <*> go `opt` e    foldlMany        :: (Alternative f) => (b -> a -> b) -> b -> f a ->   f b    foldlMany op e v =  go <*> pure e      where        go = op v (.) <*> go `opt` id    foldlSome        :: (Alternative f) => (b -> a -> b) -> b -> f a ->   f b    foldlSome op e v =  op e <\$> v <**> go      where        go = op v (.) <*> go `opt` id    foldrSepMany :: (Alternative f) => (a -> b -> b) -> b -> f c -> f a   -> f b    foldrSepMany op e u v = op <\$> v <*> go `opt` e      where        go = op <\$ u <*> v <*> go `opt` e    foldrSepSome :: (Alternative f) => (a -> b -> b) -> b -> f c -> f a   -> f b    foldrSepSome op e u v = op <\$> v <*> go      where        go = op <\$ u <*> v <*> go `opt` e    foldlSepMany :: (Alternative f) => (b -> a -> b) -> b -> f c -> f a   -> f b    foldlSepMany op e u v = op e <\$> v <**> go `opt` e      where        go = op v (.) <*> go `opt` id    foldlSepSome :: (Alternative f) => (b -> a -> b) -> b -> f c -> f a   -> f b    foldlSepSome op e u v = op e <\$> v <**> go      where        go = op v (.) <*> go `opt` id    sepMany, sepSome :: (Alternative f) => f b -> f a -> f [a]    sepMany          =  foldrSepMany (:) []    sepSome          =  foldrSepSome (:) []    chainr     :: (Alternative f) => f (a -> a -> a) -> f a -> f a    chainr u v =  v > go      where        go = u <^> v > go    chainl     :: (Alternative f) => f (a -> a -> a) -> f a -> f a    chainl u v =  v <**> go      where        go = (.) (u <^> v) <*> go `opt` id Cheers,    Stefan _______________________________________________ Libraries mailing list [hidden email] http://www.haskell.org/mailman/listinfo/libraries Idiom.hs (4K) Download Attachment
Open this post in threaded view
|

Re: PROPOSAL: Some more 'Applicative' combinators

 In reply to this post by Iavor Diatchki Iavor Diatchki wrote: > Bryan O'Sullivan wrote: >> Why not make the task specificity clearer, with a separate >> Control.Applicative.Parsing module? +1 > Now _this_ would definitely suggest that they are only good for > parsing which would be misleading. Would it? I mean, I currently don't know a second use case for them. Preferably, the names like  skipMany , endBy , sepBy etc. should still make sense in the new context. Regards, apfelmus _______________________________________________ Libraries mailing list [hidden email] http://www.haskell.org/mailman/listinfo/libraries
Open this post in threaded view
|

Re: PROPOSAL: Some more 'Applicative' combinators

 Hello, On Jan 8, 2008 1:43 AM, apfelmus <[hidden email]> wrote: > Iavor Diatchki wrote: > > Bryan O'Sullivan wrote: > >> Why not make the task specificity clearer, with a separate > >> Control.Applicative.Parsing module? > > +1 > > > Now _this_ would definitely suggest that they are only good for > > parsing which would be misleading. > > Would it? I mean, I currently don't know a second use case for them. > Preferably, the names like  skipMany , endBy , sepBy etc. should still > make sense in the new context. Yes it would.  The name Control.Applicative.Parsing certainly suggests that.    We should not overdo the granularity of the modules in the library.  What would be the benefit of having a separate module? By the way, the combinators are all variations of 'many': 'skipMany' is just like 'many'  but ignoring the results; 'endBy' performs a "cleanup" computation after each iteration; "sepBy" performs a "cleanup" operation between iterations.  As I said before, these are just ordinary control structures. -Iavor _______________________________________________ Libraries mailing list [hidden email] http://www.haskell.org/mailman/listinfo/libraries