I was reading about Applicative
in Haskell from Hutton's Programming in Haskell. To understand it better I came up with the following definition for Applicative
for lists:
-- Named as pure' and "app" to avoid confusion with builtin versions
class Applicative' f where
pure' :: a -> f a
app :: f (a->b) -> f a -> f b
instance Applicative' [] where
pure' x = [x]
app _ [] = []
app [g] (x:xs) = [(g x)] ++ app [g] xs
app (g:gs) (x:xs) = [(g x)] ++ app gs xs
-- fmap functions could be defined as:
fmap1' :: (Applicative' f)=>(a->b) -> f a -> f b
fmap1' g x = app (pure' g) x
fmap2' :: (Applicative' f)=>(a->b->c) -> f a -> f b -> f c
fmap2' g x y = app (app (pure' g) x) y
fmap3' :: (Applicative' f)=>(a->b->c->d) -> f a -> f b -> f c -> f d
fmap3' g x y z = app (app (app (pure' g) x) y) z
An example of use of fmap2'
is as follows:
Ok, one module loaded.
*Main> g = \x y -> x*y
*Main> arr1 = [1,2,3]
*Main> arr2 = [4,5,6]
*Main> fmap2' g arr1 arr2
[4,10,18]
*Main>
But the standard definition for Applicative
function <*>
for a list is defined as:
gs <*> xs = [g x | g <- gs, x <- xs]
Thus resulting in
pure (*) <*> [1,2], [3,4]
[3,4,6,8]
I was wondering why it defined in the manner of for all arr1, for all arr2, apply function
rather than take corresponding elements arr1, arr2 apply function
.
I guess the first definition is probably more useful? Are there any specific reasons for this choice?