The difference between fair and pure

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] 

Failed to match type '[] with' Maybe

Expected Type: Probably b

Actual Type: [b]

In the second argument '(<*>), namely' [0 .. 10]

In the expression: Just (* 3) <*> [0 .. 10]

In the equation for 'it: it = Just (* 3) <*> [0 .. 10]

When are pure and Just interchangeable and when are they different?

+6
source share
2 answers

pure is an overloaded operation. It is defined for all types that implement the Applicative class. One of the types that makes it Maybe . So, pure in this context coincides with Just . But there are other types that also implement Applicative , for example [] (lists). In this case, pure means singleton (i.e., a function that takes a single value and returns a singleton list that contains that value). So

 pure (*3) <*> [0..10] 

really means:

 [(*3)] <*> [0..10] 

but not

 Just (*3) <*> [0..10] 

In this last example, you are trying to mix lists with maybes, so the GHC rejects it. In general, haskell determines what the exact meaning of pure based on context, for example. if you try to use it with maybes, it will interpret it as Just , if you use it with lists, interpret it as singleton.

+10
source

The pure function returns a polymorphic value:

 Prelude> :t pure "foo" pure "foo" :: Applicative f => f [Char] 

For Maybe , pure is defined as 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 the return type indicates Haskell, for the Applicative instance, to define pure .

 Prelude> pure "foo" :: [[Char]] ["foo"] Prelude> pure "foo" :: Maybe [Char] Just "foo" 

Besides providing an explicit type, Haskell can infer which type to use the base to use the value. For example, (<*> [1..5]) :: (Num a, Enum a) => [a -> b] -> [b] , therefore in pure (+3) <*> [1..5] we know that pure (+3) must be of type [a -> b] . Similarly, in pure (+3) <*> Just 5 we know that pure (+3) must be of type Maybe (a->b) .

In general, in any expression pure f <*> g type g will determine the return type of pure f .

+6
source

All Articles