[GHC] #13191: Make liftA2 a method of Applicative

GHC ghc-devs at haskell.org
Wed Jan 16 16:57:16 UTC 2019


#13191: Make liftA2 a method of Applicative
-------------------------------------+-------------------------------------
        Reporter:  dfeuer            |                Owner:  dfeuer
            Type:  feature request   |               Status:  closed
        Priority:  normal            |            Milestone:  8.2.1
       Component:  Core Libraries    |              Version:  8.0.1
      Resolution:  fixed             |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):  Phab:D3031
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Old description:

> Some functors support implementations of `liftA2` that are considerably
> faster than the usual definition. Furthermore, some people see `liftA2`
> as more intuitive and fundamental to the idea of `Applicative` than `<*>`
> is.
>
> This has been discussed on the libraries list in
> https://mail.haskell.org/pipermail/libraries/2017-January/027579.html and
> (as an official proposal) in
> https://mail.haskell.org/pipermail/libraries/2017-January/027612.html.
> All who expressed an opinion favored the proposal. One (David Menendez)
> specified that his support was weak. The others (Conal Elliot, Kris
> Nuttycombe, Wren Romano, Bardur Arantsson, and Mario Blažević) either
> supported the proposal strongly or merely indicated they were "+1". Conal
> Elliot wrote:
> [[BR]]
> [[BR]]
>
> > +1.
> >
> > I also sometimes define a specialized `liftA2` and then use it to
> define
> > `(<*>)`, which then gets used to define the real `liftA2`.
> >
> > I think of `liftA2` as playing a role similar to `foldMap` and
> `traverse`, while
> > `(<*>)` corresponds to `fold` and `sequenceA`. The first three self-
> compose
> > nicely: `liftA2.liftA2.liftA2`, `foldMap.foldMap.foldMap`, and
> > `traverse.traverse.traverse`. With functor composition, it's so much
> nicer to
> > write `liftA2.liftA2` (in the style of `Functor`, `Foldable`, and
> `Traversable`)
> > rather than `liftA2 (<*>)`.
> [[BR]]
>
> Wren Romano wrote
> [[BR]]
> [[BR]]
>
> > I'm also all for adding liftA2 to the class and have noticed this
> > inefficiency/asymmetry when working on the class hierarchies for other
> > languages
> [[BR]]
>
> Kris NuttyCombe wrote
> [[BR]]
> [[BR]]
>
> > I'm in favor of this change. From my perspecive, liftA2 is actually the
> > fundamental Applicative operation, an <*> is merely a convenient
> > isomorphism. When I'm teaching, showing the symmetry between the
> following
> > always seems to help students:
> >
> > fmap :: (a -> b) -> f a -> f b
> > liftA2 :: (a -> b -> c) -> f a -> f b -> f c
> > flip (>>=) :: (a -> f b) -> f a -> f b
> >
> > <*> is obviously exceptionally useful in practice. But liftA2 seems
> like the
> > more essential shape of that operation.

New description:

 Some functors support implementations of `liftA2` that are considerably
 faster than the usual definition. Furthermore, some people see `liftA2` as
 more intuitive and fundamental to the idea of `Applicative` than `<*>` is.

 This has been discussed on the libraries list in
 https://mail.haskell.org/pipermail/libraries/2017-January/027579.html and
 (as an official proposal) in
 https://mail.haskell.org/pipermail/libraries/2017-January/027612.html. All
 who expressed an opinion favored the proposal. One (David Menendez)
 specified that his support was weak. The others (Conal Elliott, Kris
 Nuttycombe, Wren Romano, Bardur Arantsson, and Mario Blažević) either
 supported the proposal strongly or merely indicated they were "+1". Conal
 Elliott wrote:
 [[BR]]
 [[BR]]

 > +1.
 >
 > I also sometimes define a specialized `liftA2` and then use it to define
 > `(<*>)`, which then gets used to define the real `liftA2`.
 >
 > I think of `liftA2` as playing a role similar to `foldMap` and
 `traverse`, while
 > `(<*>)` corresponds to `fold` and `sequenceA`. The first three self-
 compose
 > nicely: `liftA2.liftA2.liftA2`, `foldMap.foldMap.foldMap`, and
 > `traverse.traverse.traverse`. With functor composition, it's so much
 nicer to
 > write `liftA2.liftA2` (in the style of `Functor`, `Foldable`, and
 `Traversable`)
 > rather than `liftA2 (<*>)`.
 [[BR]]

 Wren Romano wrote
 [[BR]]
 [[BR]]

 > I'm also all for adding liftA2 to the class and have noticed this
 > inefficiency/asymmetry when working on the class hierarchies for other
 > languages
 [[BR]]

 Kris NuttyCombe wrote
 [[BR]]
 [[BR]]

 > I'm in favor of this change. From my perspecive, liftA2 is actually the
 > fundamental Applicative operation, an <*> is merely a convenient
 > isomorphism. When I'm teaching, showing the symmetry between the
 following
 > always seems to help students:
 >
 > fmap :: (a -> b) -> f a -> f b
 > liftA2 :: (a -> b -> c) -> f a -> f b -> f c
 > flip (>>=) :: (a -> f b) -> f a -> f b
 >
 > <*> is obviously exceptionally useful in practice. But liftA2 seems like
 the
 > more essential shape of that operation.

--

Comment (by conal):

 Fix spelling of my last name ("Elliott").

-- 
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13191#comment:2>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list