There are a number of cases in the base package where the same
functionality exists under two different names. This can occur for a
number of different reasons, but most commonly it’s either:
The presence of identical (or nearly identical) functionality under different names can lead to confusion when reading code. The purpose of this page is to point out these occurrences to bypass this confusion.
GHC.OldList.concat :: [[a]] -> [a]
Prelude.concat :: Foldable t => t [a] -> [a]
mconcat :: Monoid a => [a] -> a
fold :: (Foldable t, Monoid a) => t a -> a
All four of these functions allow us to collapse down a sequence of
values into a single value. The most specific is GHC.OldList.concat:
given a list of lists, it combines all of these lists together into a
single list. The most general is fold, which leverages two
typeclasses:
Foldable typeclass to work with many more data structuresMonoidGHC.OldList.concatMap :: (a -> [b]) -> [a] -> [b]
Prelude.concatMap :: Foldable t => (a -> [b]) -> t a -> [b]
foldMap :: (Foldable t, Monoid b) => (a -> b) -> t a -> b
This is very similar to the concat/mconcat/fold breakdown
above. We can generalize from lists to instances of Foldable and
Monoid.
(*>) :: Applicative f => f a -> f b -> f b
(>>) :: Monad m => m a -> m b -> m b
The only difference between these two is Applicative vs
Monad. This is a holdover from the days when Applicative was not a
superclass of Monad.
pure :: Applicative f => a -> f a
return :: Monad m => a -> m a
return is pure specialized to Monad, relevant for the same
superclass reason above.
map :: (a -> b) -> [a] -> [b]
fmap :: Functor f => (a -> b) -> f a -> f b
liftM :: (Monad m) => (a -> b) -> m a -> m b
map is specialized to just lists, while fmap is generalized to all
Functors. Like *> vs >>, the presence of liftM is just a
holdover from the days when Functor was not a superclass of Monad.
traverse_ :: (Foldable t, Applicative f) => (a -> f b) -> t a -> f ()
mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m ()
mapM_ is traverse_ specialized to Monad, relevant for the same
superclass reason above.
sequenceA_ :: (Foldable t, Applicative f) => t (f a) -> f ()
sequence_ :: (Foldable t, Monad m) => t (m a) -> m ()
Same Monad/Applicative specialization.
traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)
mapM :: (Traversable t, Monad m) => (a -> m b) -> t a -> m (t b)
Same Monad/Applicative specialization.
sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)
sequence :: (Traversable t, Monad m) => t (m a) -> m (t a)
Same Monad/Applicative specialization.
for :: (Traversable t, Applicative f) => t a -> (a -> f b) -> f (t b)
forM :: (Traversable t, Monad m) => t a -> (a -> m b) -> m (t b)
Same Monad/Applicative specialization.
(++) :: [a] -> [a] -> [a]
Data.Semigroup.(<>) :: Semigroup a => a -> a -> a
mappend :: Monoid m => m -> m -> m
++ is simply <> and mappend specialized to lists. mappend should be the
same as <> in all cases.
Note: historically, Semigroup was not a superclass of Monoid, resulting in
<> and mappend having potentially different implementations. That no longer
applies.
Subscribe to our blog via email
Email subscriptions come from our Atom feed and are handled by Blogtrottr. You will only receive notifications of blog posts, and can unsubscribe any time.