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.
A function pointer allows a pointer to a function to be passed as a parameter to another function. Function Objects (Functors) - C++ allows the function call operator() to be overloaded, such that an object instantiated from a class can be "called" like a function.
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 .
In functional programming, a functor is a design pattern inspired by the definition from category theory, that allows for a generic type to apply a function inside without changing the structure of the generic type.
Functor Laws If two sequential mapping operations are performed one after the other using two functions, the result should be the same as a single mapping operation with one function that is equivalent to applying the first function to the result of the second.
Can type variables
aandbbe function types
– yeah, sure.
isn't it that class
Functorbecome effectively the same as classApplicative
no, absolutely not. If you insert a function type into the a or b of the fmap signature, you get things like
fmap :: ((x -> y) -> b) -> f (x -> y) -> f b
or
fmap :: (a -> p -> q) -> f a -> f (p -> q)
but crucially, fmap always takes exactly one f _ wrapped-value and spits out exactly one such value. Applicative meanwhile allows you to accept any number of wrapped values, provided you give it the a function to process the contained values.
a and b can be function types. They can be any type. In fact, a valid Functor must allow them to be any type.
To answer your Applicative question, let's try it.
fmap :: (a -> b -> c) -> f a -> f (b -> c)
Okay, great! Now I can take an f a and convert it to a f (b -> c). But.... then what? I can't apply f (b -> c) to an argument. It's not a function; it's a value of my functor type. If only we had a function with this signature...
superFmap :: f (b -> c) -> f b -> f c
But that sure does look a lot like
(<*>) :: f (b -> c) -> f b -> f c
which is a member of Applicative. Hence, we need Applicative to be able to apply this secondary result.
What the other answers said is correct. We can't implement pure either, for similar reasons. But it's important to note that we can't even get (<*>) in general, because if we could then that would imply that every Functor is Apply, which is also certainly not the case.
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