Reputation: 5405
Just (+) <*> Just 3 <*> Just 5
Just 8
pure (+) <*> Just 3 <*> Just 5
Just 8
pure (*3) <*> [0..10]
[0,3,6,9,12,15,18,21,24,27,30]
Just (*3) <*> [0..10]
Couldn't match type ‘[]’ with ‘Maybe’
Expected type: Maybe b
Actual type: [b]
In the second argument of ‘(<*>)’, namely ‘[0 .. 10]’
In the expression: Just (* 3) <*> [0 .. 10]
In an equation for ‘it’: it = Just (* 3) <*> [0 .. 10]
When are pure
and Just
interchangeable and when are they different?
Upvotes: 6
Views: 602
Reputation: 530833
The pure
function returns a polymorphic value:
Prelude> :t pure "foo"
pure "foo" :: Applicative f => f [Char]
For Maybe
, pure
is just defined to be Just
:
instance Applicative Maybe where
pure = Just
-- ...
Other types provide different definitions; as an example, it is defined for lists as
instance Applicative [] where
pure x = [x]
-- ...
Specifying a type for the return value tells Haskell which Applicative
instance to use for the definition of pure
.
Prelude> pure "foo" :: [[Char]]
["foo"]
Prelude> pure "foo" :: Maybe [Char]
Just "foo"
In addition to providing an explicit type, Haskell can infer which type to use base on how the value is used. For instance, (<*> [1..5]) :: (Num a, Enum a) => [a -> b] -> [b]
, so in pure (+3) <*> [1..5]
, we know pure (+3)
has to have type [a -> b]
. Similarly, in pure (+3) <*> Just 5
, we know that pure (+3)
must have type Maybe (a->b)
.
In general, in any expression pure f <*> g
, the type of g
will determine what type of value pure f
needs to return.
Upvotes: 7
Reputation: 23840
pure
is an overloaded operation. It is defined for all types that implement the Applicative
class. One of the types that do that is Maybe
. So pure
in that context is the same as Just
. But there are other types that also implement Applicative
such as []
(lists). In that case, pure
means singleton (i.e. the function that takes a single value and returns the one-element list that contains that value). So
pure (*3) <*> [0..10]
really means:
[(*3)] <*> [0..10]
and not
Just (*3) <*> [0..10]
In this last example you are trying to mix lists with maybes which is why GHC rejects it. In general, haskell figures out what is the exact meaning of pure
based on the context, e.g. if you try to use it with maybes, it will interpret it as Just
, if you use it with lists interpret it as singleton.
Upvotes: 11