Вопрос

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?

Это было полезно?

Решение

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top