
From: http://en.wikibooks.org/wiki/Haskell/Applicative_Functors ============================= import Control.Applicative f :: (a -> b -> c) fmap :: Functor f => (d -> e) -> f d -> f e fmap f :: Functor f => f a -> f (b -> c) -- Identify d with a, and e with (b -> c) sumsqr :: Int -> Int -> Int -- my f sumsqr i j = i*i+j*j ============================= I'm trying to understand how the above works but... [michael@localhost ~]$ ghci GHCi, version 6.12.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Loading package ffi-1.0 ... linking ... done. Prelude> :l bozo.hs [1 of 1] Compiling Main ( bozo.hs, interpreted ) bozo.hs:5:0: Invalid type signature Failed, modules loaded: none. Prelude> Michael

On 26 August 2010 15:56, michael rice
From: http://en.wikibooks.org/wiki/Haskell/Applicative_Functors
============================= import Control.Applicative
f :: (a -> b -> c) fmap :: Functor f => (d -> e) -> f d -> f e fmap f :: Functor f => f a -> f (b -> c) -- Identify d with a, and e with (b -> c)
sumsqr :: Int -> Int -> Int -- my f sumsqr i j = i*i+j*j =============================
The line with the error is the one beginning with "fmap f :: ..."; you can't provide a variable/parameter on the left hand side of the :: Also, why are you trying to re-define fmap? -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com

Yeah, I figured as much, but the code is copied right off the referenced page.
Michael
--- On Thu, 8/26/10, Ivan Lazar Miljenovic
From: http://en.wikibooks.org/wiki/Haskell/Applicative_Functors
============================= import Control.Applicative
f :: (a -> b -> c) fmap :: Functor f => (d -> e) -> f d -> f e fmap f :: Functor f => f a -> f (b -> c) -- Identify d with a, and e with (b -> c)
sumsqr :: Int -> Int -> Int -- my f sumsqr i j = i*i+j*j =============================
The line with the error is the one beginning with "fmap f :: ..."; you can't provide a variable/parameter on the left hand side of the :: Also, why are you trying to re-define fmap? -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com

On 26 August 2010 16:09, michael rice
Yeah, I figured as much, but the code is copied right off the referenced page.
Because as Vo Minh Thu says, it was there as a demonstration; in this instance they were doing "algebraic" manipulation of the code and corresponding type signatures. Admittedly, the wording could have been improved... -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com

Can you recommend an example that works?
Michael
--- On Thu, 8/26/10, Ivan Lazar Miljenovic
Yeah, I figured as much, but the code is copied right off the referenced page.
Because as Vo Minh Thu says, it was there as a demonstration; in this instance they were doing "algebraic" manipulation of the code and corresponding type signatures. Admittedly, the wording could have been improved... -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com

OK, fmap2 works, but not fmap3. What am I not understanding?
Michael
import Control.Applicative
-- f :: (a -> b -> c)
-- fmap :: Functor f => (d -> e) -> f d -> f e
sumsqr :: Int -> Int -> Int
sumsqr i j = i*i+j*j
-- fmap :: Functor f => f a -> f (b -> c) -- Identify d with a, and e with (b -> c)
fmap2 f a b = f `fmap` a <*> b
fmap3 f a b c = f `fmap` a <*> b <*> c
fmap4 f a b c d = f `fmap` a <*> b <*> c <*> d
-- fmap2 f a b = f <$> a <*> b
-- fmap3 f a b c = f <$> a <*> b <*> c
-- fmap4 f a b c d = f <$> a <*> b <*> c <*> d
*Main> fmap2 sumsqr (Just 3) (Just 4)
Just 25
*Main> fmap3 sumsqr (Just 3) (Just 4) (Just 5)
<interactive>:1:6:
Couldn't match expected type `a2 -> b' against inferred type `Int'
In the first argument of `fmap3', namely `sumsqr'
In the expression: fmap3 sumsqr (Just 3) (Just 4) (Just 5)
In the definition of `it':
it = fmap3 sumsqr (Just 3) (Just 4) (Just 5)
*Main>
--- On Thu, 8/26/10, Ivan Lazar Miljenovic
Can you recommend an example that works?
An example of what? The definitions of fmap2, etc. on that page look like they're correct. -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com

On 26 August 2010 16:47, michael rice
OK, fmap2 works, but not fmap3. What am I not understanding?
Michael
import Control.Applicative
-- f :: (a -> b -> c) -- fmap :: Functor f => (d -> e) -> f d -> f e
sumsqr :: Int -> Int -> Int sumsqr i j = i*i+j*j
-- fmap :: Functor f => f a -> f (b -> c) -- Identify d with a, and e with (b -> c)
fmap2 f a b = f `fmap` a <*> b fmap3 f a b c = f `fmap` a <*> b <*> c fmap4 f a b c d = f `fmap` a <*> b <*> c <*> d
-- fmap2 f a b = f <$> a <*> b -- fmap3 f a b c = f <$> a <*> b <*> c -- fmap4 f a b c d = f <$> a <*> b <*> c <*> d
*Main> fmap2 sumsqr (Just 3) (Just 4) Just 25 *Main> fmap3 sumsqr (Just 3) (Just 4) (Just 5)
<interactive>:1:6: Couldn't match expected type `a2 -> b' against inferred type `Int' In the first argument of `fmap3', namely `sumsqr' In the expression: fmap3 sumsqr (Just 3) (Just 4) (Just 5) In the definition of `it': it = fmap3 sumsqr (Just 3) (Just 4) (Just 5) *Main>
sumsqr takes three arguments; fmap3 has type: fmap3 :: (a -> b -> c -> d) -> Maybe a -> Maybe b -> Maybe c -> Maybe d i.e. the function you pass it needs to take 3 arguments. fmap3 (\ x y z -> z * y + z) (Just 1) (Just 2) (Just 3)
--- On Thu, 8/26/10, Ivan Lazar Miljenovic
wrote: From: Ivan Lazar Miljenovic
Subject: Re: [Haskell-cafe] On to applicative To: "michael rice" Cc: haskell-cafe@haskell.org Date: Thursday, August 26, 2010, 2:33 AM On 26 August 2010 16:29, michael rice
wrote: Can you recommend an example that works?
An example of what?
The definitions of fmap2, etc. on that page look like they're correct.
-- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com
-- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com

Hmm... it was my understanding that the example was showing how to *avoid* having to create a lot of functions that do the same thing but have different numbers of arguments.
From the Wiki page:
"Anytime you feel the need to define different higher order functions to
accommodate for function-arguments with a different number of arguments,
think about how defining a proper instance of Applicative can make your life easier."
Not so?
Michael
--- On Thu, 8/26/10, Ivan Lazar Miljenovic
OK, fmap2 works, but not fmap3. What am I not understanding?
Michael
import Control.Applicative
-- f :: (a -> b -> c) -- fmap :: Functor f => (d -> e) -> f d -> f e
sumsqr :: Int -> Int -> Int sumsqr i j = i*i+j*j
-- fmap :: Functor f => f a -> f (b -> c) -- Identify d with a, and e with (b -> c)
fmap2 f a b = f `fmap` a <*> b fmap3 f a b c = f `fmap` a <*> b <*> c fmap4 f a b c d = f `fmap` a <*> b <*> c <*> d
-- fmap2 f a b = f <$> a <*> b -- fmap3 f a b c = f <$> a <*> b <*> c -- fmap4 f a b c d = f <$> a <*> b <*> c <*> d
*Main> fmap2 sumsqr (Just 3) (Just 4) Just 25 *Main> fmap3 sumsqr (Just 3) (Just 4) (Just 5)
<interactive>:1:6: Couldn't match expected type `a2 -> b' against inferred type `Int' In the first argument of `fmap3', namely `sumsqr' In the expression: fmap3 sumsqr (Just 3) (Just 4) (Just 5) In the definition of `it': it = fmap3 sumsqr (Just 3) (Just 4) (Just 5) *Main>
sumsqr takes three arguments; fmap3 has type: fmap3 :: (a -> b -> c -> d) -> Maybe a -> Maybe b -> Maybe c -> Maybe d i.e. the function you pass it needs to take 3 arguments. fmap3 (\ x y z -> z * y + z) (Just 1) (Just 2) (Just 3)
--- On Thu, 8/26/10, Ivan Lazar Miljenovic
wrote: From: Ivan Lazar Miljenovic
Subject: Re: [Haskell-cafe] On to applicative To: "michael rice" Cc: haskell-cafe@haskell.org Date: Thursday, August 26, 2010, 2:33 AM On 26 August 2010 16:29, michael rice
wrote: Can you recommend an example that works?
An example of what?
The definitions of fmap2, etc. on that page look like they're correct.
-- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com
-- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com

This is indeed the case: if you want to apply your sumsqr function or
Ivan's (\ x y z -> z * y + z), to some Functor (Maybe in this case),
you don't have to redefine them, or even to use fmap2 or fmap3: you
just have to use <$> and <*>.
E.g.:
(\ a b c -> a + b + c) <$> Just 1 <*> Just 2 <*> Just 3
2010/8/26 michael rice
Hmm... it was my understanding that the example was showing how to *avoid* having to create a lot of functions that do the same thing but have different numbers of arguments.
From the Wiki page:
"Anytime you feel the need to define different higher order functions to accommodate for function-arguments with a different number of arguments, think about how defining a proper instance of Applicative can make your life easier."
Not so?
Michael
--- On Thu, 8/26/10, Ivan Lazar Miljenovic
wrote: From: Ivan Lazar Miljenovic
Subject: Re: [Haskell-cafe] On to applicative To: "michael rice" Cc: haskell-cafe@haskell.org Date: Thursday, August 26, 2010, 2:50 AM On 26 August 2010 16:47, michael rice
wrote: OK, fmap2 works, but not fmap3. What am I not understanding?
Michael
import Control.Applicative
-- f :: (a -> b -> c) -- fmap :: Functor f => (d -> e) -> f d -> f e
sumsqr :: Int -> Int -> Int sumsqr i j = i*i+j*j
-- fmap :: Functor f => f a -> f (b -> c) -- Identify d with a, and e with (b -> c)
fmap2 f a b = f `fmap` a <*> b fmap3 f a b c = f `fmap` a <*> b <*> c fmap4 f a b c d = f `fmap` a <*> b <*> c <*> d
-- fmap2 f a b = f <$> a <*> b -- fmap3 f a b c = f <$> a <*> b <*> c -- fmap4 f a b c d = f <$> a <*> b <*> c <*> d
*Main> fmap2 sumsqr (Just 3) (Just 4) Just 25 *Main> fmap3 sumsqr (Just 3) (Just 4) (Just 5)
<interactive>:1:6: Couldn't match expected type `a2 -> b' against inferred type `Int' In the first argument of `fmap3', namely `sumsqr' In the expression: fmap3 sumsqr (Just 3) (Just 4) (Just 5) In the definition of `it': it = fmap3 sumsqr (Just 3) (Just 4) (Just 5) *Main>
sumsqr takes three arguments; fmap3 has type:
fmap3 :: (a -> b -> c -> d) -> Maybe a -> Maybe b -> Maybe c -> Maybe d
i.e. the function you pass it needs to take 3 arguments.
fmap3 (\ x y z -> z * y + z) (Just 1) (Just 2) (Just 3)
--- On Thu, 8/26/10, Ivan Lazar Miljenovic
wrote: From: Ivan Lazar Miljenovic
Subject: Re: [Haskell-cafe] On to applicative To: "michael rice" Cc: haskell-cafe@haskell.org Date: Thursday, August 26, 2010, 2:33 AM On 26 August 2010 16:29, michael rice
wrote: Can you recommend an example that works?
An example of what?
The definitions of fmap2, etc. on that page look like they're correct.
-- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com
-- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On 26 Aug 2010, at 08:01, michael rice wrote:
Hmm... it was my understanding that the example was showing how to *avoid* having to create a lot of functions that do the same thing but have different numbers of arguments.
From the Wiki page:
"Anytime you feel the need to define different higher order functions to accommodate for function-arguments with a different number of arguments, think about how defining a proper instance of Applicative can make your life easier."
Not so?
Very much so – instead of defining liftA2, liftA3 etc like this, just use pure to get things into the applicative, and write <*> instead of ' ' to apply applicatives and you're done. Don't write liftA3 sumsq (Just 3) (Just 4) (Just 5) Write (pure sumsq) <*> (pure 3) <*> (pure 4) <*> (pure 5) or you can get rid of that first pure with a quick fmap: sumsq <$> (pure 3) <*> (pure 4) <*> (pure 5) Bob

A lot of stuff to get one's head around. Was aware of liftM2, liftM3, etc., but not liftA2, liftA3, etc.
So, the statement was true, but not the way that was shown in the example, i.e., with fmap2, fmap3, etc., which required different functions for each of the fmaps.
Thanks. Appreciate the patience.
Michael
--- On Thu, 8/26/10, Thomas Davie
From the Wiki page:
"Anytime you feel the need to define different higher order functions to accommodate for function-arguments with a different number of arguments, think about how defining a proper instance of Applicative can make your life easier." Not so? Very much so – instead of defining liftA2, liftA3 etc like this, just use pure to get things into the applicative, and write <*> instead of ' ' to apply applicatives and you're done. Don't writeliftA3 sumsq (Just 3) (Just 4) (Just 5) Write(pure sumsq) <*> (pure 3) <*> (pure 4) <*> (pure 5) or you can get rid of that first pure with a quick fmap:sumsq <$> (pure 3) <*> (pure 4) <*> (pure 5) Bob

On Aug 26, 2010, at 12:34 AM, michael rice wrote:
A lot of stuff to get one's head around. Was aware of liftM2, liftM3, etc., but not liftA2, liftA3, etc.
liftM and liftA are essentially equivalent (and are both essentially equivalent to fmap) Same for the liftAn = liftMn functions (where n is an integer). Applicative functors are more general than monads, so it makes sense for them to have their own functions. It is a matter of history that liftM was defined before liftA.
So, the statement was true, but not the way that was shown in the example, i.e., with fmap2, fmap3, etc., which required different functions for each of the fmaps.
Strictly speaking, fmap will work with a function in more than one argument, as long as it is properly typed. This is what makes applicative functors work. Consider that a function f :: a -> b -> c also has the type f :: a -> (b -> c). If you feed it an "a", (resulting in a value of the form f a), you get a function g :: (b -> c). In other words, every function is a function in one argument. Some functions just happen to map to other functions. <$> is flip fmap. f <$> functor = fmap f functor Consider what happens if f :: a -> b. (f <$> functor) means "pull an a out of the functor, apply f, and return a functor "over" some b. That is to say, "lift" f into the functor and apply it. Now consider what happens if f :: a -> (b -> c). By analogy, this means "pull an a out of the functor object, apply f, and return a functor object (f g) :: f (b -> c)" (In other words, a functor object that "contains" a function g :: b -> c). In order to get a c value out of this, you need to apply g to "something". But note that we're not just dealing with g. It is "in" the functor already, and so doesn't need lifting. So some smart guy wrote a function called <*> :: (Functor f) => f (b -> c) -> f b -> f c that does just that. This is one of the defining functions for an applicative functor. (And part of the reason for the name. If the functor contains a function, you can "apply the functor" to properly typed functor objects.) The other function is pure :: (a -> b) -> f (a -> b). It takes a function and lifts it into the functor, without applying it to anything. In other words, given an f :: a -> b, pure f <*> functor = f <$> functor If f has a bigger type (say, a -> b -> c -> d), you can do things like: f <$> functor_on_a <*> functor_on_b <*> functor_on_c Every monad is an applicative functor. If we have a monad action m_f :: m (a -> b), and another one m_a :: (m a), we can get a monad action in type (m b) by pulling the function f :: a -> b out of the first one and applying it to the b in the second one: m_f >>= (\f -> liftM f m_a) or... m_f >>= (flip liftM) m_a In fact, there is a function called ap :: m (a -> b) -> m a -> m b which does just that, and is "essentially equivalent" to <*>. Of course, running return on a function f is equivalent to running pure on f.

On Aug 26, 2010, at 1:29 AM, Alexander Solla wrote:
The other function is pure :: (a -> b) -> f (a -> b). It takes a function and lifts it into the functor, without applying it to anything. In other words, given an f :: a -> b,
My mistake, though if you got the rest of it, it should come as no surprise that pure :: a -> f a and is essentially equivalent to a monad's return.

Hi Alexander,
Didn't get to sleep till 4 AM and it took me a while to go though your post.
So far...
--- On Thu, 8/26/10, Alexander Solla
A lot of stuff to get one's head around. Was aware of liftM2, liftM3, etc., but not liftA2, liftA3, etc.
liftM and liftA are essentially equivalent (and are both essentially equivalent to fmap) Same for the liftAn = liftMn functions (where n is an integer). Applicative functors are more general than monads, so it makes sense for them to have their own functions. It is a matter of history that liftM was defined before liftA.
So, the statement was true, but not the way that was shown in the example, i.e., with fmap2, fmap3, etc., which required different functions for each of the fmaps.
Strictly speaking, fmap will work with a function in more than one argument, as long as it is properly typed. This is what makes applicative functors work. Consider that a function f :: a -> b -> c also has the type f :: a -> (b -> c). If you feed it an "a", (resulting in a value of the form f a), you get a function g :: (b -> c). In other words, every function is a function in one argument. ### Knew that fact, but it needed to be dusted off. Some functions just happen to map to other functions. <$> is flip fmap. f <$> functor = fmap f functor #### Brent Yorgey's post noted. #### "map to"? Take as arguments? Consider what happens if f :: a -> b. (f <$> functor) means "pull an a out of the functor, apply f, and return a functor "over" some b. That is to say, "lift" f into the functor and apply it. #### OK. #### Prelude Control.Applicative> let double x = x+x #### Prelude Control.Applicative> (double <$> (Just 7)) #### Just 14 Now consider what happens if f :: a -> (b -> c). By analogy, this means "pull an a out of the functor object, apply f, and return a functor object (f g) :: f (b -> c)" (In other words, a functor object that "contains" a function g :: b -> c). In order to get a c value out of this, you need to apply g to "something". But note that we're not just dealing with g. It is "in" the functor already, and so doesn't need lifting. So some smart guy wrote a function called <*> :: (Functor f) => f (b -> c) -> f b -> f c #### Prelude Control.Applicative> let plus x y = x+y #### Prelude Control.Applicative> let f = (plus <$> (Just 3)) #### Prelude Control.Applicative> f (Just 4) #### <interactive>:1:0: #### Couldn't match expected type `Maybe t1 -> t' #### against inferred type `Maybe (Integer -> Integer)' #### In the expression: f (Just 4) #### In the definition of `it': it = f (Just 4) #### Prelude Control.Applicative> f <*> (Just 4) #### Just 7 #### OK. Partial evaluation with functors? that does just that. This is one of the defining functions for an applicative functor. (And part of the reason for the name. If the functor contains a function, you can "apply the functor" to properly typed functor objects.) The other function is pure :: (a -> b) -> f (a -> b). It takes a function and lifts it into the functor, without applying it to anything. In other words, given an f :: a -> b, pure f <*> functor = f <$> functor #### Prelude Control.Applicative> pure double <*> (Just 5) #### Just 10 #### Not so, the f got applied or where did we get the 10? Not sure, is this the #### "mistake" you point out in your second post? #### Two ways of doing the same thing? #### 1) #### Prelude Control.Applicative> (double <$> (Just 7)) #### Just 14 #### 2) #### Prelude Control.Applicative> pure double <*> (Just 7) #### Just 14 #### Still looking at rest of your post. If f has a bigger type (say, a -> b -> c -> d), you can do things like: f <$> functor_on_a <*> functor_on_b <*> functor_on_c Every monad is an applicative functor. If we have a monad action m_f :: m (a -> b), and another one m_a :: (m a), we can get a monad action in type (m b) by pulling the function f :: a -> b out of the first one and applying it to the b in the second one: m_f >>= (\f -> liftM f m_a) or... m_f >>= (flip liftM) m_a In fact, there is a function called ap :: m (a -> b) -> m a -> m b which does just that, and is "essentially equivalent" to <*>. Of course, running return on a function f is equivalent to running pure on f. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Aug 26, 2010, at 9:27 AM, michael rice wrote:
Some functions just happen to map to other functions.
<$> is flip fmap. f <$> functor = fmap f functor #### Brent Yorgey's post noted.
#### "map to"? Take as arguments?
"maps to" as in "outputs".
pure f <*> functor = f <$> functor
#### Prelude Control.Applicative> pure double <*> (Just 5) #### Just 10
#### Not so, the f got applied or where did we get the 10? Not sure, is this the #### "mistake" you point out in your second post?
double is getting applied in that expression, but it isn't because of pure. The <*> operator is pulling double out of pure double (which equals Just double in this case), and applying it to Just 5. My correction was to point out that pure's type is more general than I had said. Instead of pure :: (a -> b) -> f (a -> b), it is pure :: a -> f a -- which includes (a -> b) -> f (a -> b) as a special case. In fact, pure and return are "essentially equivalent" in form. So you could write out your verification case as (pure double <*> pure 5) :: Just Int to further decouple your code from the particular functor you're working with. (You need the type annotation to run it in GHCi)
#### Two ways of doing the same thing?
#### 1) #### Prelude Control.Applicative> (double <$> (Just 7)) #### Just 14
#### 2) #### Prelude Control.Applicative> pure double <*> (Just 7) #### Just 14
Indeed.

When I began looking into applicative, I googled "haskell applicative" and grabbed the first one on the list, the wikipage. I think a better choice would have been the "Learn You a Haskell" section on functors/applicative, the second one on the list. I'm going to spend some time there but will no doubt be back before long with another question.
Thanks all,
Michael
--- On Thu, 8/26/10, Alexander Solla
Some functions just happen to map to other functions.
<$> is flip fmap. f <$> functor = fmap f functor #### Brent Yorgey's post noted.
#### "map to"? Take as arguments?
"maps to" as in "outputs".
pure f <*> functor = f <$> functor
#### Prelude Control.Applicative> pure double <*> (Just 5) #### Just 10
#### Not so, the f got applied or where did we get the 10? Not sure, is this the #### "mistake" you point out in your second post?
double is getting applied in that expression, but it isn't because of pure. The <*> operator is pulling double out of pure double (which equals Just double in this case), and applying it to Just 5. My correction was to point out that pure's type is more general than I had said. Instead of pure :: (a -> b) -> f (a -> b), it is pure :: a -> f a -- which includes (a -> b) -> f (a -> b) as a special case. In fact, pure and return are "essentially equivalent" in form. So you could write out your verification case as (pure double <*> pure 5) :: Just Int to further decouple your code from the particular functor you're working with. (You need the type annotation to run it in GHCi)
#### Two ways of doing the same thing?
#### 1) #### Prelude Control.Applicative> (double <$> (Just 7)) #### Just 14
#### 2) #### Prelude Control.Applicative> pure double <*> (Just 7) #### Just 14
Indeed._______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

I think it works well :)
But sumsqr has type Int -> Int -> Int, not Int -> Int -> Int -> Int.
I.e. it does take only two arguments while fmap3 takes a function of
three arguments.
2010/8/26 michael rice
OK, fmap2 works, but not fmap3. What am I not understanding?
Michael
import Control.Applicative
-- f :: (a -> b -> c) -- fmap :: Functor f => (d -> e) -> f d -> f e
sumsqr :: Int -> Int -> Int sumsqr i j = i*i+j*j
-- fmap :: Functor f => f a -> f (b -> c) -- Identify d with a, and e with (b -> c)
fmap2 f a b = f `fmap` a <*> b fmap3 f a b c = f `fmap` a <*> b <*> c fmap4 f a b c d = f `fmap` a <*> b <*> c <*> d
-- fmap2 f a b = f <$> a <*> b -- fmap3 f a b c = f <$> a <*> b <*> c -- fmap4 f a b c d = f <$> a <*> b <*> c <*> d
*Main> fmap2 sumsqr (Just 3) (Just 4) Just 25 *Main> fmap3 sumsqr (Just 3) (Just 4) (Just 5)
<interactive>:1:6: Couldn't match expected type `a2 -> b' against inferred type `Int' In the first argument of `fmap3', namely `sumsqr' In the expression: fmap3 sumsqr (Just 3) (Just 4) (Just 5) In the definition of `it': it = fmap3 sumsqr (Just 3) (Just 4) (Just 5) *Main>
--- On Thu, 8/26/10, Ivan Lazar Miljenovic
wrote: From: Ivan Lazar Miljenovic
Subject: Re: [Haskell-cafe] On to applicative To: "michael rice" Cc: haskell-cafe@haskell.org Date: Thursday, August 26, 2010, 2:33 AM On 26 August 2010 16:29, michael rice
wrote: Can you recommend an example that works?
An example of what?
The definitions of fmap2, etc. on that page look like they're correct.
-- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

2010/8/26 michael rice
From: http://en.wikibooks.org/wiki/Haskell/Applicative_Functors
============================= import Control.Applicative
f :: (a -> b -> c) fmap :: Functor f => (d -> e) -> f d -> f e fmap f :: Functor f => f a -> f (b -> c) -- Identify d with a, and e with (b -> c)
sumsqr :: Int -> Int -> Int -- my f sumsqr i j = i*i+j*j =============================
I'm trying to understand how the above works but...
[michael@localhost ~]$ ghci GHCi, version 6.12.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Loading package ffi-1.0 ... linking ... done. Prelude> :l bozo.hs [1 of 1] Compiling Main ( bozo.hs, interpreted )
bozo.hs:5:0: Invalid type signature Failed, modules loaded: none. Prelude>
Hi, The fifth line has the form x y :: ... instead of x :: ... This is not a legal type signature. Furthermore, you can't give fmap two signatures in the same source file. The reason this is given on the page you linked is for demonstration purpose (well, I guess, I haven't read it). Cheers, Thu
participants (6)
-
Alexander Solla
-
Brent Yorgey
-
Ivan Lazar Miljenovic
-
michael rice
-
Thomas Davie
-
Vo Minh Thu