bit confused. fmap
sounds like it can map
all over a list of Maybe
's, but I can't get it to work if I use e.g. fApplyFunctor = (+1) <$> [Just 1, Just 2]
.
What seems to work perfectly fine is: map ((+1) <$>) [Just 1, Just 2, Just 3]
. This seems to be overkill in that sense that I recall fmap
could do that by itself already...
Functor is a type class that abstracts over type constructors that can be map 'ed over. Examples of such type constructors are List , Option , and Future .
yes map is a functor.
Whenever we want to apply a function on each element of a given list and produce a new list consisting of the updated elements, then we make use of a function called map() function in Haskell and this map() function takes a list and the function to be applied on each element in the list as an input and returns a new ...
The expression fmap (*2) is a function that takes a functor f over numbers and returns a functor over numbers. That functor can be a list, a Maybe , an Either String, whatever. The expression fmap (replicate 3) will take a functor over any type and return a functor over a list of elements of that type.
No fmap
means you can map over an arbitrary Functor
type (well think about it for now as a collection), but you only do this one "functor level" deep. In case you fmap
with a list, it is exactly equivalent to map
.
fmap
however is defined over all sorts of Functor
s, like lists, Maybe
s, etc. Here you can thus fmap
in the fmap
to map over two levels:
fApplyFunctor = fmap (fmap (+1)) [Just 1, Just 2]
This will then result in:
Prelude> fmap (fmap (+1)) [Just 1, Just 2]
[Just 2,Just 3]
Prelude> (fmap (+1)) <$> [Just 1, Just 2]
[Just 2,Just 3]
Prelude> ((+1) <$>) <$> [Just 1, Just 2]
[Just 2,Just 3]
EDIT: like @DanielWagner says, there exists a data type Compose
which works over two (or more if you cascade) Functor
s and thus allows us to fmap
two levels deep. This is implemented like:
newtype Compose f g a = Compose { getCompose :: f (g a) } instance (Functor f, Functor g) => Functor (Compose f g) where fmap f (Compose x) = Compose (fmap (fmap f) x)
so here we again perform an fmap
on two levels:
Prelude Data.Functor.Compose> getCompose ((+1) <$> Compose [Just 1, Just 2])
[Just 2,Just 3]
But as you see it requires some syntax to first wrap the data in a Compose
, and then to later "unwrap" it out of the Compose
, so this requires some extra work as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With