*fmap*type signature to someone, and discovered that it was a lot easier than the first time I tried to understand (or explain) some of the Linq type signatures. The issue was trying to figure out what "things" can be passed to

*fmap*, and what can be expected back. Here is a sample

**ghci**session that I used to explain just that.

-- let's give ourselves a nice prompt Prelude> :set prompt "ghci> " -- ok, now, what's the type signature for fmap? ghci> :type fmap fmap :: (Functor f) => (a -> b) -> f a -> f b -- Aha! So we see that it takes a function, and a Functor. I think we -- know how to create, or how to recognize a function (a -> b). -- What about Functors, what can we plug there? ghci> :info Functor class Functor f where fmap :: (a -> b) -> f a -> f b (GHC.Base.<$) :: a -> f b -> f a -- Defined in GHC.Base instance Functor Maybe -- Defined in Data.Maybe instance Functor [] -- Defined in GHC.Base instance Functor IO -- Defined in GHC.Base -- Interesting. A Functor is not a data type, but a typeclass. -- An interface, for those of us with OO background. -- Furthermore, we see that the following types implement the -- Functor typeclass: Maybe, [], and IO. -- So it would seem that fmap allows us to apply a function to a value -- wrapped inside a Functor. Let's find something that we can use -- test this. ghci> :module +Data.Time ghci> :type getCurrentTime getCurrentTime :: IO UTCTime -- So, the getCurrentTime function returns to us a UTCTime wrapped -- in the IO monad. Furthermore, we have seen that IO implements Functor, -- so IO UTCTime could fit the bill for the "f a" that we have a -- need for in fmap. Now we need a function that takes -- a UTCTime and returs something. Hmmm... Let's turn to hoogle -- (at http://www.haskell.org/hoogle/) and search for functions that have -- (UTCTime -> a) type signature. Ah! There is one, let's check it out: ghci> :type utctDay utctDay :: UTCTime -> Day -- This UTCTime -> Day also fits the (a -> b) that we need for fmap! -- So, recapping: -- for fmap :: (Functor f) => (a -> b) -> f a -> f b -- we have: -- utctDay :: UTCTime -> Day for the place of (a -> b) -- getCurrentTime :: IO UTCTime for the place of f a -- ... and according to fmap's type, we should expect IO Day as a result. -- Let's check: ghci> :t fmap utctDay getCurrentTime fmap utctDay getCurrentTime :: IO Day -- Great! All the ends match :) Let's see what this does: ghci> fmap utctDay getCurrentTime 2010-09-09That was pretty easy, wasn't it?

## No comments:

Post a Comment