2016-09-18 1 views
1

Je suis aux prises avec un exercice de Haskell Book (Chapitre 16. Functor). Compte tenu de ce qui suit, il me attend de définir fmap:Comment écrire l'instance Functor pour ce type?

{-# LANGUAGE FlexibleInstances #-} 

newtype Flip f a b = 
    Flip (f b a) 
    deriving (Eq, Show) 

newtype K a b = 
    K a 

instance Functor (Flip K a) where 
    fmap = undefined 

Dans un exercice précédent, je l'ai déjà fait ce qui suit:

data K a b = 
    K a 

instance Functor (K a) where 
    fmap f (K x) = K x 

Mais pour cela Flip a b, je ne peux même pas comprendre comment commencer, par exemple comment continuer fmap f Flip ....

Je pensais que peut-être avant de le faire que je devrais aussi écrire un foncteur pour le newtype K a b, semblable à ce que je faisais data K a b:

instance Functor (K a) where 
    fmap f (K x) = K x 

Mais je ne peux pas comprendre comment procéder à l'instance Functor pour Flip f a b .

Des idées, des conseils?

+2

Enfin, je suis venu avec quelque chose qui vérifie le type: 'Functor d'instance (Flip K a) où fmap f (Flip (K x)) = Flip (K (f x))'. Mais maintenant je ne peux pas m'expliquer (je ne sais même pas si c'est correct). –

Répondre

1

Jetons un coup d'oeil à votre solution:

instance Functor (Flip K a) where 
    fmap f (Flip (K a)) = Flip (K (f b)) 

Qu'est-ce que Flip (K a) signifie réellement?

K est le foncteur constant, que vous avez implémenté correctement. Il ne tient pas compte de la fonction f et renvoie toujours K a. Mais ce qui se passe réellement dans les coulisses, c'est que la valeur K a b est transformée en K a c. Même si la fonction f n'a pas été prise en compte, le deuxième type de K a été modifié en fonction du type f.

Maintenant, si nous FlipK, nous nous tournons simplement autour des arguments:

Flip (K a b) == K b a 

Au lieu d'avoir une valeur constante et en ignorant la fonction, nous avons une valeur de changement et un type « ignoré » constant. En regardant la mise en œuvre avec les signatures de type explicites nous obtenons:

instance Functor (Flip K a) where 
    fmap :: (b -> c) -> Flip K a b -> Flip K a c -- or: 
    fmap :: (b -> c) -> K b a -> K c a 
    fmap f (Flip (K a)) = Flip (K (f b)) 

Comme vous avez déjà conclu, la seule mise en œuvre possible est celle ci-dessus.

Vous pouvez voir les cas d'utilisation d'un foncteur Constant dans la question this.