Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Define methods for subclasses of type classes

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?

like image 475
ThePiercingPrince Avatar asked Feb 15 '14 15:02

ThePiercingPrince


People also ask

Which methods can be defined in a subclass?

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 ; ...

What is subclass method in Java?

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).

Which methods are defined in a class?

Methods are functions that belongs to the class. There are two ways to define functions that belongs to a class: Inside class definition.

Can subclass have its own methods?

Subclass can not access parent private properties (fields) and methods. It can access public , protected and default properties and methods only.


2 Answers

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
like image 197
Petr Avatar answered Oct 20 '22 07:10

Petr


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.

like image 31
Sibi Avatar answered Oct 20 '22 07:10

Sibi