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