I tried this:
class Functor f where
fmap :: (a -> b) -> f a -> f b
class (Functor f) => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
fmap f x = pure f <*> x
I got this:
`fmap' is not a (visible) method of class `Applicative'
How to define fmap
for Applicative
and other subclasses of Functor
?
Classes in Java exist in a hierarchy. A class in Java can be declared as a subclass of another class using the extends keyword. A subclass inherits variables and methods from its superclass and can use them as if they were declared within the subclass itself: class Animal { float weight ; ...
In the Java language, classes can be derived from other classes, thereby inheriting fields and methods from those classes. Definitions: A class that is derived from another class is called a subclass (also a derived class, extended class, or child class).
Methods are functions that belongs to the class. There are two ways to define functions that belongs to a class: Inside class definition.
Subclass can not access parent private properties (fields) and methods. It can access public , protected and default properties and methods only.
What you're asking for isn't (yet) implemented for Haskell. However, there is a proposal for such a feature called Default Superclass Instances, which would allow you to do declare:
class Functor f => Applicative f where
return :: x -> f x
(<*>) :: f (s -> t) -> f s -> f t
instance Functor f where
fmap = (<*>) . pure
You are understanding this wrong: there are no subclasses concept playing anywhere.
When there is a class constraint like this: class (Functor f) => Applicative f
, it means that for defining some type to be an Applicative
instance, it should be already an instance of Functor
.
Consider the datatype Maybe
:
You define its Functor
instance like this:
instance Functor Maybe where
fmap _ Nothing = Nothing
fmap f (Just a) = Just (f a)
and its Applicative
instance like this:
instance Applicative Maybe where
pure = Just
(Just f) <*> (Just x) = Just (f x)
_ <*> _ = Nothing
As seen in the example above, you cannot define new function named fmap
in Applicative
instance just because it has its class constraint. The class constraint just tells you that Applicative
instance should already be an instance of Functor
typeclass. You have to define fmap
function while creating Functor
instance, because that's what the Functor
typeclass needs but not the Applicative
one.
Also, your typeclass should look like this:
class Functor f where
fmap :: (a -> b) -> f a -> f b
class (Functor f) => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
You don't need to put fmap
additionally into the Applicative
typeclass also. The class constraint implies that all types having Applicative
need to have fmap
defined.
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