Il s'agit donc en fait d'une référence à un article de Meijer et de quelques autres intitulé " Programmation fonctionnelle avec des bananes, des lentilles, des enveloppes et des barbelés ", l'idée de base est que nous pouvons prendre n'importe quel type de données récursives, comme par exemple
data List = Cons Int List | Nil
et nous pouvons factoriser la récursivité dans une variable de type
data ListF a = Cons Int a | Nil
la raison pour laquelle j'ai ajouté cela F
parce que c'est maintenant un foncteur! Cela nous permet également d'imiter des listes, mais avec une torsion: pour construire des listes, nous devons imbriquer le type de liste
type ThreeList = ListF (ListF (ListF Void)))
Pour récupérer notre liste d'origine, nous devons continuer à l'imbriquer indéfiniment . Cela nous donnera un type ListFF
où
ListF ListFF == ListFF
Pour ce faire, définissez un "type de point fixe"
data Fix f = Fix {unfix :: f (Fix f)}
type ListFF = Fix ListF
En tant qu'exercice, vous devriez vérifier que cela satisfait notre équation ci-dessus. Maintenant, nous pouvons enfin définir ce que sont les bananes (catamorphismes)!
type ListAlg a = ListF a -> a
ListAlg
s sont le type "d'algèbres de liste", et nous pouvons définir une fonction particulière
cata :: ListAlg a -> ListFF -> a
cata f = f . fmap (cata f) . unfix
En outre
cata :: ListAlg a -> ListFF -> a
cata :: (Either () (Int, a) -> a) -> ListFF -> a
cata :: (() -> a) -> ((Int, a) -> a) -> ListFF -> a
cata :: a -> (Int -> a -> a) -> ListFF -> a
cata :: (Int -> a -> a) -> a -> [Int] -> a
Semble familier? cata
est exactement le même que les plis droits!
Ce qui est vraiment intéressant, c'est que nous pouvons faire cela plus que de simples listes, tout type qui est défini avec ce "point fixe d'un foncteur" a un cata
et pour les accomder, il suffit de relâcher la signature de type
cata :: (f a -> a) -> Fix f -> a
Ceci est en fait inspiré d'un morceau de théorie des catégories sur lequel j'ai écrit , mais c'est la viande du côté Haskell.