How to understand the fmap here ?

The following code snippets is from xmonad: -- Given a window, find the screen it is located on, and compute -- the geometry of that window wrt. that screen. floatLocation :: Window -> X (ScreenId, W.RationalRect) --....... rr <- snd `fmap` floatLocation w Prelude> :i fmap class Functor f where fmap :: (a -> b) -> f a -> f b It seems it is different from the definition of fmap ? sincerely! 2009-05-05 z_axis

2009/5/5 z_axis
The following code snippets is from xmonad: -- Given a window, find the screen it is located on, and compute -- the geometry of that window wrt. that screen. floatLocation :: Window -> X (ScreenId, W.RationalRect) --....... rr <- snd `fmap` floatLocation w
Prelude> :i fmap class Functor f where fmap :: (a -> b) -> f a -> f b
It seems it is different from the definition of fmap ? sincerely!
X is a Functor (and a Monad). floatLocation w :: X (ScreenId, W.RationalRect) -- i.e. f is X and a is (ScreenId, W.RationalRect) snd :: (ScreenId, W.RationalRect) -> W.RationalRect fmap :: (same as snd) -> X (ScreenId, W.RationalRect) -> X W.RationalRect Makes sense ? Cheers, Thu

On 5 May 2009, at 11:27, z_axis wrote:
The following code snippets is from xmonad: -- Given a window, find the screen it is located on, and compute -- the geometry of that window wrt. that screen. floatLocation :: Window -> X (ScreenId, W.RationalRect) --....... rr <- snd `fmap` floatLocation w
Prelude> :i fmap class Functor f where fmap :: (a -> b) -> f a -> f b
It seems it is different from the definition of fmap ? sincerely!
As the type signature of fmap explains, it transforms a function. Specifically, it starts with a function (a -> b), and it transforms it to accept an 'a' inside a functor instead of just an a, and return a 'b' inside the same functor instead of just a b. In other words, fmap applies functions inside containers. We can see from floatLocation that it returns a pair inside a container - specifically, an X container. Fmap takes snd, and transforms it to work on values inside the X. So, snd has type (a,b) -> b, thus fmap snd has type f (a,b) -> f b. In this case, the type it's being applied to is X (ScreenId, W.RationalRect), so f unifies with X, a with ScreenID and b with W.RationalRect. Making snd `fmap` floatLocation w hav the type X W.RationalRect. Finally, the bind into rr there takes it out of the X monad all together, getting you a W.RationalRect. You may want to read this article which explains some of Haskell's abstraciton mechanisms: http://noordering.wordpress.com/2009/03/31/how-you-shouldnt-use-monad/ Bob

Hello z_axis, Tuesday, May 5, 2009, 1:27:16 PM, you wrote:
floatLocation :: Window -> X (ScreenId, W.RationalRect)
rr <- snd `fmap` floatLocation w
class Functor f where fmap :: (a -> b) -> f a -> f b
looks ok. X===f, fmap executes floatLocation w :: X (ScreenId, W.RationalRect) === f a and then applies snd :: (ScreenId, W.RationalRect) -> W.RationalRect === a->b to result, so that entire (snd `fmap` floatLocation w) has type X W.RationalRect === f b -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com
participants (4)
-
Bulat Ziganshin
-
minh thu
-
Thomas Davie
-
z_axis