In Haskell, the class Functor is declared as:
class Functor f where
fmap :: (a -> b) -> f a -> f b
Can type variables a and b be function types, or must they be non-function types?
If they can be function types, isn't it that class Functor become effectively the same as class Applicative, in terms of making fmap able to apply to functions with arbitrary number of arguments? According to what Programming in Haskell by Hutton says:
Functors abstract the idea of
fmapmapping a function over each element of a structure. Applicatives generalize this idea to allowfmapmapping functions with any number of arguments to be mapped, rather than being restricted to functions with a single argument.
In applicative:
fmap0 :: a -> f a fmap0 = pure fmap1 :: (a -> b) -> f a -> f b fmap1 g x = pure g <*> x fmap2 :: (a -> b -> c) -> f a -> f b -> f c fmap2 g x y = pure g <*> x <*> y fmap3 :: (a -> b -> c -> d) -> f a -> f b -> f c -> f d fmap3 g x y z = pure g <*> x <*> y <*> z
Class Applicative is declared as:
class Functor f => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b
Thanks.
aandbcan be function types. - Willem Van Onsemfmap1usesApplicativemethods. This shows that just havingApplicativeis enough to implementFunctor. But your question asks the other way: is just havingFunctorenough to implementApplicative? I think if you try to go the other way -- try to write down implementations ofpureand(<*>)just usingfmap(and pure things) on the right-hand side -- you will find yourself stuck quite quickly indeed. - Daniel Wagnerbcan be a function type is whyApplicativeexists:fmap (+) (Just 3) == Just (+3).Applicativeis what lets you apply the result of a partial application of+to anotherJustvalue.fmap (+) (Just 3) <*> Just 5 == Just (+3) <*> Just 5 == Just 8. - chepner