liftA2 exported from Prelude

The patch to export liftA2 from Prelude has just landed in GHC.
This means that you can expect the change to come to you with the next major GHC release (likely 9.6).

This is a breaking change - please see the migration guide if you think it might affect you.

This change is motivated by a few things:

  • liftA2 is an often used function, even more so than (<*>) for some
    people.
  • When implementing Applicative, the compiler will prompt you for either
    an implementation of (<*>), or of liftA2, but trying to use the latter
    ends with an error, without further imports. This could be confusing
    for newbies.
  • For teaching, it is often times easier to introduce liftA2 first,
    as it is a natural generalisation of fmap.
  • This change seems to have been unanimously and enthusiastically
    accepted by the CLC members, possibly indicating a lot of love for it.
  • This change causes very limited breakage.

Please see the discussion over at Export `liftA2` from `Prelude` · Issue #50 · haskell/core-libraries-committee · GitHub if you want more context.

14 Likes

Many thanks to @googleson78 for pushing this through! We now need a hero to work on foldl' in Prelude.

6 Likes

Great to see movement and engagement on core libraries.

2 Likes

I never understood why aren’t all class methods exported btw…

I would like to tackle this. Can we export foldMap’ as well?

…before everyone else nominates their favourite “non-lazy” entities to be added to the Prelude (at least the ones which aren’t type-class methods): would having them together in auxiliary Strict submodules e.g. Data.Foldable.Strict containing foldl', foldMap', etc be a more viable alternative - perhaps even a Prelude.Strict module?

What is the aim in adding them to a Data.Foldable.Strict? They’re already exported from e.g. Data.Foldable. I think the goal with adding them to Prelude is to have them available with no extra steps (i.e. to reduce how much you have to go out of your way to do “the right thing”).

…etc.

They’re already exported from e.g. Data.Foldable.

Then they can go into Prelude.Strict for now, with Data.Foldable.Strict to appear later.

I think the goal with adding them to Prelude is to have them available with no extra steps […]

@Wismill I think it’s reasonable to export class Foldable from Prelude in full, current situation is quite annoying.

5 Likes

o_0 … foldl' isn’t a Foldable method. Considering that there’s already ten of them, are any more methods really needed?

@atravers you are up to a big surprise then. I told you, current situation is annoying.

…?

I have no idea what your last links are supposed to demonstrate. My point was that foldl' is indeed a member of Foldable: Data.Foldable

…17 methods isn’t a “big surprise” - it’s a big disappointment. The only two essential methods are foldr and foldMap - the other 15 can just be free-standing overloaded definitions.

But if this style of agglomeration is considered “best practice” these days…can:

  • unit :: {...} => a -> m a

  • map :: {...} => (a -> b) -> (m a -> m b)

  • join :: {...} => m (m a) -> m a

now be added to the Monad class - I suspect the categorists amongst us would find the current situation annoying, too (oh, and Eq could have back (/=) too, since that change has apparently caused some pedagogical problems…).

Someone brought up the same questions on haskell-cafe some years ago. The reason why Foldable has so many functions is for efficiency reasons.

…before or after the appearance of {-# RULES #-} and {-# SPECIALISE [...] #-} ?

Personally I take the large number of methods as an indicator that Foldable is a pretty poor abstraction that doesn’t really capture anything precisely.