I'm trying to do what must be blindingly obvious in Haskell, which is go from Just [1]
and Just [2]
to Just [1, 2]
. However I can't find anything online as I keep finding related but unhelpful pages. So, how do you achieve this?

- 2,252
- 4
- 29
- 53
4 Answers
You can use liftA2 (++)
:
liftA2 (++) :: Maybe [a] -> Maybe [a] -> Maybe [a]
liftA2
just lifts a binary function into an Applicative
. Applicative
s were designed for lifting functions of arbitrary arguments in a context, so they're perfect for this. In this case, the Applicative
we're using is Maybe
. To see how this works, we can look at the definition:
liftA2 :: (Applicative f) => (a -> b -> c) -> f a -> f b -> f c
liftA2 f a b = f <$> a <*> b
(<$>)
just lifts any function on pure values to one operating inside f
: (a -> b) -> f a -> f b
. (It's just an alias for fmap
, if you're familiar with Functor
s.) For Maybe
:
_ <$> Nothing = Nothing
f <$> Just x = Just (f x)
(<*>)
is a bit trickier: it applies a function inside f
to a value inside f
: f (a -> b) -> f a -> f b
. For Maybe
:
Just f <*> Just x = Just (f x)
_ <*> _ = Nothing
(In fact, f <$> x
is the same thing as pure f <*> x
, which is Just f <*> x
for Maybe
.)
So, we can expand the definition of liftA2 (++)
:
liftA2 (++) a b = (++) <$> a <*> b
-- expand (<$>)
liftA2 (++) (Just xs) b = Just (xs ++) <*> b
liftA2 (++) _ _ = Nothing
-- expand (<*>)
liftA2 (++) (Just xs) (Just ys) = Just (xs ++ ys)
liftA2 (++) _ _ = Nothing
Indeed, we can use these operators to lift a function of any number of arguments into any Applicative
, just by following the pattern of liftA2
. This is called applicative style, and is very common in idiomatic Haskell code. In this case, it might even be more idiomatic to use it directly by writing (++) <$> a <*> b
, if a
and b
are already variables. (On the other hand, if you're partially applying it — say, to pass it to a higher-order function — then liftA2 (++)
is preferable.)
Every Monad
is an Applicative
, so if you ever find yourself trying to "lift" a function into a context, Applicative
is probably what you're looking for.

- 40,602
- 3
- 180
- 182
-
Awesome :) Thanks, you've saved me tearing my hair out. Don't suppose you know an equivalent for `[2]` and `Just [3]` -> `Just [2, 3]` do you? :) – Dean Barnes Jan 24 '12 at 18:44
-
4@DeanBarnes: `(2 :) <$> Just [3]` – Joey Adams Jan 24 '12 at 18:45
-
Fantastic answer, thank you @ehird! This is basically my reference from now on :) – Dean Barnes Jan 24 '12 at 18:50
-
2You're welcome! :) To generalise what @JoeyAdams said, `(xs ++) <$> mys` works for prepending any `xs :: [a]` inside an `mys :: Maybe [a]`. – ehird Jan 24 '12 at 19:01
while @ehird's answer is great, I would have used a noobish solution in the form:
mergeJust a b = do
a' <- a
b' <- b
return (a' ++ b')

- 53,238
- 27
- 117
- 198

- 10,378
- 7
- 39
- 55
-
2+1 even noobs, equipped with simple tools, can solve this problem. You could also write the same as a monad comprehension: `[a' ++ b' | a' <- a, b' <- b]` – Dan Burton Jan 24 '12 at 22:01
To expand the solution to a list of Just
s, you could use
fmap join $ sequence [Just[1],Just[2],Just[3]]
-- Just [1,2,3]

- 54,104
- 13
- 100
- 195
Since it was not mentioned in other solutions, I'll say it here. The simplest way to accomplish your task, in my opinion, is to use a <>
(or mappend
) from Data.Monoid
.
import Data.Monoid
Just [1,2] <> Just [7,8] == Just [1,2,7,8]
However, note that this solution, unlike ehird's applicative solution, will not short-circuit on Nothing
values.
Just [1,2] <> Nothing ---> Just [1,2]
--However
(++) <$> Just [1,2] <*> Nothing ---> Nothing

- 3,500
- 1
- 20
- 41