7 votes

Est-ce que (fmap f) est la même chose que (f .) si f est une fonction de type a->b ?

Je suis en train d'essayer de mettre en œuvre une instance Functor de

data ComplicatedA a b
    = Con1 a b
    | Con2 [Maybe (a -> b)]

Pour Con2, ma réflexion a été que le fmap doit ressembler à quelque chose comme

fmap f (Con2 xs) = Con2 (map f' xs)

puis j'ai besoin d'avoir une fonction map de liste f' comme

Maybe (a -> x) -> Maybe (a -> y)

Étant donné que Maybe est un Functor, je peux écrire f' comme

fmap ((a->x) -> (a->y))

Pour obtenir ((a->x) -> (a->y)), j'ai pensé que je pourrais simplement faire fmap (x->y) ce qui est la même chose que (fmap f)

Alors ma solution était

instance Functor (ComplicatedA a) where
    fmap f (Con1 x y) = Con1 x (f y)
    fmap f (Con2 xs) = Con2 (map (fmap (fmap f)) xs)

Cependant, la vraie solution utilise (f .) au lieu de (fmap f) pour obtenir ((a->x) -> (a->y)) de x -> y et cela ressemble à ceci

instance Functor (ComplicatedA a) where
    fmap f (Con1 a b) = Con1 a (f b)
    fmap f (Con2 l) = Con2 (map (fmap (f .)) l)

Je me demandais juste quel était le problème avec ma réflexion et ma solution. Est-ce que (fmap f) est la même chose que (f .) si f est une fonction de type a->b?

Merci d'avance.

6voto

duplode Points 3803

Les solutions sont en effet équivalentes. fmap pour le funiteur de fonction/lecteur est (.):

instance Functor ((->) r) where
    fmap = (.)

((->) r est le constructeur de type de fonction utilisé avec une syntaxe préfixée -- (->) r a est le même que r -> a.)

L'intuition est que, comme vous l'avez noté, (.) :: (x -> y) -> (a -> x) -> (a -> y) utilise une fonction x -> y pour modifier les résultats d'une fonction a -> x.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X