Ok, regardons concat
.
Tout d'abord, voici l'implémentation :
concat :: [[a]] -> [a]
concat = foldr (++) []
Cela correspond à la structure de votre h
donde Maybe
est remplacé par []
et, de manière plus significative, []
est remplacé par - pour abuser de la syntaxe pendant un moment - [[]]
.
[[]]
est aussi un foncteur, bien sûr, mais c'est pas a Functor
instance de la manière dont la condition de naturalité l'utilise. Traduire directement votre exemple ne fonctionnera pas :
concat . fmap k
=/= fmap k . concat
...parce que les deux fmap
ne travaillent que sur la partie la plus extérieure []
.
Et bien que [[]]
est hypothétiquement une instance valide de Functor
vous ne pouvez pas en faire une directement, pour des raisons pratiques qui sont probablement évidentes.
Cependant, vous pouvez reconstruire la levée correcte de la manière suivante :
concat . (fmap . fmap) k
== fmap k . concat
...où fmap . fmap
est équivalent à l'implémentation de fmap
pour un hypothétique Functor
instance pour [[]]
.
Comme un addendum connexe, return
est gênant pour la raison inverse : a -> f a
est une transformation naturelle d'un foncteur d'identité élidé. En utilisant : []
l'identité s'écrirait comme suit :
(:[]) . ($) k
== fmap k . (:[])
...où le complètement superflu ($)
remplace ce qui serait fmap
sur le foncteur d'identité élidé.