Proposal: Adding Kleisli composition to Control.Monad

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
36 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Proposal: Adding Kleisli composition to Control.Monad

Donald Bruce Stewart
http://hackage.haskell.org/trac/ghc/ticket/997

Add Kleisli composition to Control.Monad.

Kleisli composition of monads is a foundational feature missing from the
current Control.Monad library. A recent discussion revealed solid
support for its inclusion.

This patch adds:

    (>=>) :: (Monad m) => (a -> m b) -> (b -> m c) -> (a -> m c)
    (<=<) :: (Monad m) => (b -> m c) -> (a -> m b) -> (a -> m c)

Along with the useful control combinator:

    forever :: (Monad m) => m a -> m ()

Traditionally, >=> has been written as @@, however to support the
flipped version, new notation seems to be required. It should be notated
that there is overlap with the Kleisli class in Control.Arrow
(specifically >>>), however, short of a convenient unifying form for
Arrow and Monad, a monad-specific >>> seems reasonable. To mirror >>>
and =<<, infixr 1 was chosen.

Proposal period: 2 weeks.
Deadline: 27th November.

-- Don

------------------------------------------------------------------------

hunk ./Control/Monad.hs 40
+    , (>=>)         -- :: (Monad m) => (a -> m b) -> (b -> m c) -> (a -> m c)
+    , (<=<)         -- :: (Monad m) => (b -> m c) -> (a -> m b) -> (a -> m c)
+    , forever       -- :: (Monad m) => m a -> m ()
hunk ./Control/Monad.hs 179
+infixr 1 <=<, >=>
+
+-- | Left-to-right Kleisli composition of monads.
+(>=>)       :: Monad m => (a -> m b) -> (b -> m c) -> (a -> m c)
+f >=> g     = \x -> f x >>= g
+
+-- | Right-to-left Kleisli composition of monads. '(>=>)', with the arguments flipped
+(<=<)       :: Monad m => (b -> m c) -> (a -> m b) -> (a -> m c)
+(<=<)       = flip (>=>)
+
+-- | @'forever' act@ repeats the action infinitely.
+forever     :: (Monad m) => m a -> m ()
+forever a   = a >> forever a

------------------------------------------------------------------------
_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Adding Kleisli composition to Control.Monad

Mattias Bengtsson
On Mon, 2006-11-13 at 13:15 +1100, Donald Bruce Stewart wrote:
> http://hackage.haskell.org/trac/ghc/ticket/997

[snip]

> Along with the useful control combinator:
>
>     forever :: (Monad m) => m a -> m ()

[snip]

> +-- | @'forever' act@ repeats the action infinitely.
> +forever     :: (Monad m) => m a -> m ()
> +forever a   = a >> forever a

I would personally rather see repeatM and repeatM_ like the
replicateM/replicateM_ pair already in Control.Monad.

I implement them like this:
repeatM  = sequence  . repeat
repeatM_ = sequence_ . repeat

Google CodeSearch tells me it's the way replicateM was implemented too:
<a href="http://www.google.com/codesearch?hl=en&lr=&q=replicateM+file%3A%5C.hs%">http://www.google.com/codesearch?hl=en&lr=&q=replicateM+file%3A%5C.hs%
24&btnG=Search

Btw, i hope it is ok to give my opinion on this. Im asking since im not
a library developer or anything just a normal programmer.

_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries

signature.asc (196 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Adding Kleisli composition to Control.Monad

Donald Bruce Stewart
moonlite:

> On Mon, 2006-11-13 at 13:15 +1100, Donald Bruce Stewart wrote:
> > http://hackage.haskell.org/trac/ghc/ticket/997
>
> [snip]
>
> > Along with the useful control combinator:
> >
> >     forever :: (Monad m) => m a -> m ()
>
> [snip]
>
> > +-- | @'forever' act@ repeats the action infinitely.
> > +forever     :: (Monad m) => m a -> m ()
> > +forever a   = a >> forever a
>
> I would personally rather see repeatM and repeatM_ like the
> replicateM/replicateM_ pair already in Control.Monad.
>
> I implement them like this:
> repeatM  = sequence  . repeat
> repeatM_ = sequence_ . repeat
>
> Google CodeSearch tells me it's the way replicateM was implemented too:
> <a href="http://www.google.com/codesearch?hl=en&lr=&q=replicateM+file%3A%5C.hs%">http://www.google.com/codesearch?hl=en&lr=&q=replicateM+file%3A%5C.hs%
> 24&btnG=Search
>
> Btw, i hope it is ok to give my opinion on this. Im asking since im not
> a library developer or anything just a normal programmer.

On this topic, we can go back to:
    http://www.mail-archive.com/cvs-all@.../msg26511.html

However, it was pointed out that repeatM is next to useless, and it is
traditional to use 'forever' for repeatM_ (see for example "Tackling the
Awkward Squad", and http://haskell.org/haskellwiki/Roll_your_own_IRC_bot

That being said, repeatM_ isn't too bad, should people prefer it.

-- Don
_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Adding Kleisli composition to Control.Monad

Neil Mitchell
Hi

> However, it was pointed out that repeatM is next to useless, and it is
> traditional to use 'forever' for repeatM_ (see for example "Tackling the
> Awkward Squad", and http://haskell.org/haskellwiki/Roll_your_own_IRC_bot
>
> That being said, repeatM_ isn't too bad, should people prefer it.

If I had to guess what the monadic version of repeat was, I'd guess
repeatM_ before forever. Forever is a very overloaded word, repeat in
Haskell has exactly one concrete meaning agreed by everyone (since its
in the Prelude).

Thanks

Neil
_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Adding Kleisli composition to Control.Monad

Donald Bruce Stewart
ndmitchell:

> Hi
>
> >However, it was pointed out that repeatM is next to useless, and it is
> >traditional to use 'forever' for repeatM_ (see for example "Tackling the
> >Awkward Squad", and http://haskell.org/haskellwiki/Roll_your_own_IRC_bot
> >
> >That being said, repeatM_ isn't too bad, should people prefer it.
>
> If I had to guess what the monadic version of repeat was, I'd guess
> repeatM_ before forever. Forever is a very overloaded word, repeat in
> Haskell has exactly one concrete meaning agreed by everyone (since its
> in the Prelude).

Agreed. But 'forever' is a pretty special control structures, worthy of
a special name. Consider the cuteness of:

    listen = forever $ do
        h <- get
        s <- io (hGetLine h)
        io (putStrLn s)
        if ping s then pong s
                  else eval (clean s)

versus:

    listen = repeatM_ $ do
        h <- get
        s <- io (hGetLine h)
        io (putStrLn s)
        if ping s then pong s
                  else eval (clean s)

Or, to quote the awkward squad, s2.4 "Control structures":
   
  > We can easily express an infinite loop as a combinator:
  >
  >     forever :: IO () -> IO ()
  >     forever a = a >> forever a

I'm we're going to use this forever more, then a name more meaningful
than repeatM_ might be appropriate (personally, I have to check every
time whether it is replicate or repeat that is :: Int -> a -> [a]).

-- Don
_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re[2]: Proposal: Adding Kleisli composition to Control.Monad

Bulat Ziganshin-2
In reply to this post by Mattias Bengtsson
Hello Mattias,

Monday, November 13, 2006, 5:51:23 AM, you wrote:

> Btw, i hope it is ok to give my opinion on this. Im asking since im not
> a library developer or anything just a normal programmer.

.. and you think that this list is for crazies only? :D


--
Best regards,
 Bulat                            mailto:[hidden email]

_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Adding Kleisli composition to Control.Monad

John Meacham
In reply to this post by Donald Bruce Stewart
On Mon, Nov 13, 2006 at 02:27:12PM +1100, Donald Bruce Stewart wrote:
> I'm we're going to use this forever more, then a name more meaningful
> than repeatM_ might be appropriate (personally, I have to check every
> time whether it is replicate or repeat that is :: Int -> a -> [a]).

now it will be three times easier to remember, as you only need to
remember what one of repeat, repeatM, and repeatM_ do to easily
determine what the other two do. standard naming conventions are very
nice when they fit so well, as they do in this case.

        John

--
John Meacham - ⑆repetae.net⑆john⑈
_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Adding Kleisli composition to Control.Monad

Donald Bruce Stewart
john:

> On Mon, Nov 13, 2006 at 02:27:12PM +1100, Donald Bruce Stewart wrote:
> > I'm we're going to use this forever more, then a name more meaningful
> > than repeatM_ might be appropriate (personally, I have to check every
> > time whether it is replicate or repeat that is :: Int -> a -> [a]).
>
> now it will be three times easier to remember, as you only need to
> remember what one of repeat, repeatM, and repeatM_ do to easily
> determine what the other two do. standard naming conventions are very
> nice when they fit so well, as they do in this case.
>

Ok :)

I'll resubmit 'repeatM_' as a separate patch.

-- Don
_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re[2]: Proposal: Adding Kleisli composition to Control.Monad

Bulat Ziganshin-2
Hello Donald,

Monday, November 13, 2006, 1:25:19 PM, you wrote:

>> > I'm we're going to use this forever more, then a name more meaningful

i prefer 'forever' name


--
Best regards,
 Bulat                            mailto:[hidden email]

_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Adding Kleisli composition to Control.Monad

Ross Paterson
In reply to this post by John Meacham
On Mon, Nov 13, 2006 at 02:02:36AM -0800, John Meacham wrote:
> On Mon, Nov 13, 2006 at 02:27:12PM +1100, Donald Bruce Stewart wrote:
> > I'm we're going to use this forever more, then a name more meaningful
> > than repeatM_ might be appropriate (personally, I have to check every
> > time whether it is replicate or repeat that is :: Int -> a -> [a]).
>
> now it will be three times easier to remember, as you only need to
> remember what one of repeat, repeatM, and repeatM_ do to easily
> determine what the other two do. standard naming conventions are very
> nice when they fit so well, as they do in this case.

I'm not so sure.  The only connection between repeatM_ and lists would
be the near-useless repeatM.

_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Adding Kleisli composition to Control.Monad

Conor McBride
In reply to this post by Donald Bruce Stewart
Hi

Just a remark, not necessarily an objection.

Don wrote:
> forever' act@ repeats the action infinitely.
> +forever     :: (Monad m) => m a -> m ()
> +forever a   = a >> forever a
>  

This forever operation is definable for any (Applicative m), not just
(Monad m). Of course, there are plenty of other operators in the library
whose types are restrictive in the same way. There's clearly a pragmatic
issue here. As it is not currently the case that a Monad instance
automatically yields an Applicative instance, it may be more convenient
in the short term to stick with the more restrictive version here and
generalise later, if ever it becomes pain-free to do so.

Cheers

Conor

_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Adding Kleisli composition to Control.Monad

roconnor
In reply to this post by Ross Paterson
I think that both repeatM and repeatM_ should be added for the following
reasons.

1. sequence . repeat and sequence_ . repeat are the only specifications
that will ever be meant by the names repeatM and repeatM_ (in
Control.Monad), so there is no concern for conflict or confusing with
these names.

2. the implemention are exteremely short, so there is negligable harm in
including them in distributions.

3. repeatM seems plausibly useful in at least the reader monad, and
probably others.

That being said, I also think it is a fine idea to add the forever
function.  Haskell thrives on multiple ways of doing the same thing.
Giving users reasonable set of options is a good thing.

--
Russell O'Connor                                      <http://r6.ca/>
``All talk about `theft,''' the general counsel of the American Graphophone
Company wrote, ``is the merest claptrap, for there exists no property in
ideas musical, literary or artistic, except as defined by statute.''
_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Adding Kleisli composition to Control.Monad

Donald Bruce Stewart
In reply to this post by Donald Bruce Stewart
dons:

> http://hackage.haskell.org/trac/ghc/ticket/997
>
> Add Kleisli composition to Control.Monad.
>
> Kleisli composition of monads is a foundational feature missing from the
> current Control.Monad library. A recent discussion revealed solid
> support for its inclusion.
>
> This patch adds:
>
>     (>=>) :: (Monad m) => (a -> m b) -> (b -> m c) -> (a -> m c)
>     (<=<) :: (Monad m) => (b -> m c) -> (a -> m b) -> (a -> m c)

Does anyone have an opinion about these guys? :)

-- Don
_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Adding Kleisli composition to Control.Monad

Henning Thielemann
In reply to this post by Donald Bruce Stewart

On Mon, 13 Nov 2006, Donald Bruce Stewart wrote:

> > I would personally rather see repeatM and repeatM_ like the
> > replicateM/replicateM_ pair already in Control.Monad.
> >
> > I implement them like this:
> > repeatM  = sequence  . repeat
> > repeatM_ = sequence_ . repeat
> >
> > Google CodeSearch tells me it's the way replicateM was implemented too:
> > <a href="http://www.google.com/codesearch?hl=en&lr=&q=replicateM+file%3A%5C.hs%">http://www.google.com/codesearch?hl=en&lr=&q=replicateM+file%3A%5C.hs%
> > 24&btnG=Search
> >
> > Btw, i hope it is ok to give my opinion on this. Im asking since im not
> > a library developer or anything just a normal programmer.
>
> On this topic, we can go back to:
>     http://www.mail-archive.com/cvs-all@.../msg26511.html
>
> However, it was pointed out that repeatM is next to useless, and it is
> traditional to use 'forever' for repeatM_ (see for example "Tackling the
> Awkward Squad", and http://haskell.org/haskellwiki/Roll_your_own_IRC_bot
>
> That being said, repeatM_ isn't too bad, should people prefer it.

I prefer repeatM_ in analogy to List.repeat.
_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Adding Kleisli composition to Control.Monad

Malcolm Wallace
In reply to this post by Donald Bruce Stewart
[hidden email] (Donald Bruce Stewart) wrote:

> > Add Kleisli composition to Control.Monad.
> >
> >     (>=>) :: (Monad m) => (a -> m b) -> (b -> m c) -> (a -> m c)
> >     (<=<) :: (Monad m) => (b -> m c) -> (a -> m b) -> (a -> m c)
>
> Does anyone have an opinion about these guys? :)

No.  :-)  I've never used them, nor wanted to, so I have no opinion.
I can see the nice compositional pattern they embody though.

Regards,
    Malcolm
_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Adding Kleisli composition to Control.Monad

Henning Thielemann

On Mon, 13 Nov 2006, Malcolm Wallace wrote:

> [hidden email] (Donald Bruce Stewart) wrote:
>
> > > Add Kleisli composition to Control.Monad.
> > >
> > >     (>=>) :: (Monad m) => (a -> m b) -> (b -> m c) -> (a -> m c)
> > >     (<=<) :: (Monad m) => (b -> m c) -> (a -> m b) -> (a -> m c)
> >
> > Does anyone have an opinion about these guys? :)
>
> No.  :-)  I've never used them, nor wanted to, so I have no opinion.
> I can see the nice compositional pattern they embody though.

Strange, the first time, I used them, was processing HTML data parsed by
HaXML. :-)
_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Adding Kleisli composition to Control.Monad

Malcolm Wallace
Henning Thielemann <[hidden email]> wrote:

> > > > Add Kleisli composition to Control.Monad.
> > > >
> > > >     (>=>) :: (Monad m) => (a -> m b) -> (b -> m c) -> (a -> m c)
> > > >     (<=<) :: (Monad m) => (b -> m c) -> (a -> m b) -> (a -> m c)
> > >
> > > Does anyone have an opinion about these guys? :)
> >
> > No.  :-)  I've never used them, nor wanted to, so I have no opinion.
> > I can see the nice compositional pattern they embody though.
>
> Strange, the first time, I used them, was processing HTML data parsed
> by HaXML. :-)

Oops, egg-on-face time.  I had forgotten about that.  Yes, the HaXml
combinators use Kleisli composition extensively (although it is called
`o` there.  And I only recognised that ContentFilter is a monad *very*
recently.)

Regards,
    Malcolm
_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Adding Kleisli composition to Control.Monad

Taral
In reply to this post by Donald Bruce Stewart
On 11/13/06, Donald Bruce Stewart <[hidden email]> wrote:
> >     (>=>) :: (Monad m) => (a -> m b) -> (b -> m c) -> (a -> m c)
> >     (<=<) :: (Monad m) => (b -> m c) -> (a -> m b) -> (a -> m c)
>
> Does anyone have an opinion about these guys? :)

I want them. See my timeout patch for a case where I wanted one of
these and didn't have it (the catch filter expression).

--
Taral <[hidden email]>
"You can't prove anything."
    -- Gödel's Incompetence Theorem
_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Adding Kleisli composition to Control.Monad

Taral
On 11/13/06, Taral <[hidden email]> wrote:
> On 11/13/06, Donald Bruce Stewart <[hidden email]> wrote:
> > >     (>=>) :: (Monad m) => (a -> m b) -> (b -> m c) -> (a -> m c)
> > >     (<=<) :: (Monad m) => (b -> m c) -> (a -> m b) -> (a -> m c)
> >
> > Does anyone have an opinion about these guys? :)
>
> I want them. See my timeout patch for a case where I wanted one of
> these and didn't have it (the catch filter expression).

Actually, my tests indicate that (>>>) and (<<<) can be used for any
Monad. So are we defining these again?

--
Taral <[hidden email]>
"You can't prove anything."
    -- Gödel's Incompetence Theorem
_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Adding Kleisli composition to Control.Monad

Wolfram Kahl
In reply to this post by Donald Bruce Stewart
 >
 > dons:
 > > http://hackage.haskell.org/trac/ghc/ticket/997
 > >
 > > Add Kleisli composition to Control.Monad.
 > >
 > > Kleisli composition of monads is a foundational feature missing from the
 > > current Control.Monad library. A recent discussion revealed solid
 > > support for its inclusion.
 > >
 > > This patch adds:
 > >
 > >     (>=>) :: (Monad m) => (a -> m b) -> (b -> m c) -> (a -> m c)
 > >     (<=<) :: (Monad m) => (b -> m c) -> (a -> m b) -> (a -> m c)
 >
 > Does anyone have an opinion about these guys? :)

Wee need the functions, no matter which names.

That said, I still like (=>>=) and (=<<=) better,
but I'm not strongly opposed to the proposed names ---
it's just that they sort of look like
they might be more closely related with Ord than with Monad.


Wolfram
_______________________________________________
Libraries mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/libraries
12