Ich möchte cata
von recursion-schemes
Paket für Listen in der Kirche Codierung verwenden können.Catamorphismen für Church-codierte Listen
type ListC a = forall b. (a -> b -> b) -> b -> b
Ich benutzte einen zweiten Rang-Typ für die Bequemlichkeit, aber das ist mir egal. Fühlen Sie sich frei, eine newtype
hinzuzufügen, verwenden Sie GADTs usw., wenn Sie das Gefühl haben, dass es notwendig ist.
Die Idee der Kirche Codierung ist weithin bekannt und einfach:
three :: a -> a -> a -> List1 a
three a b c = \cons nil -> cons a $ cons b $ cons c nil
Im Grunde genommen „abstrakt nicht spezifiziert“ cons
und nil
anstelle von „normalen“ Konstrukteuren verwendet. Ich glaube, dass alles auf diese Weise kodiert werden kann (Maybe
, Bäume, etc.).
Es ist leicht zu zeigen, dass List1
in den normalen Listen tatsächlich isomorph ist:
toList :: List1 a -> [a]
toList f = f (:) []
fromList :: [a] -> List1 a
fromList l = \cons nil -> foldr cons nil l
So seine Basis Funktors ist die gleiche wie von Listen, und es sollte möglich sein, es zu implementieren project
und verwenden Sie die Maschinen aus recursion-schemes
.
Aber ich konnte nicht, also meine Frage ist "wie mache ich das?". Für den normalen Listen, kann ich Muster Spiel gerade:
decons :: [a] -> ListF a [a]
decons [] = Nil
decons (x:xs) = Cons x xs
Da ich nicht Muster-Match auf Funktionen können, muss ich eine Falte verwenden, um die Liste zu dekonstruieren. Ich konnte eine Falte basierte project
für normale Listen schreiben:
decons2 :: [a] -> ListF a [a]
decons2 = foldr f Nil
where f h Nil = Cons h []
f h (Cons hh t) = Cons h $ hh : t
jedoch scheiterte ich es für Church-kodierte Listen anpassen:
-- decons3 :: ListC a -> ListF a (ListC a)
decons3 ff = ff f Nil
where f h Nil = Cons h $ \cons nil -> nil
f h (Cons hh t) = Cons h $ \cons nil -> cons hh (t cons nil)
cata
hat die folgende Signatur:
cata :: Recursive t => (Base t a -> a) -> t -> a
Um es mit meinen Listen zu verwenden, brauche ich:
- Um die Basis Funktors Typ für die Liste deklarieren mit
type family instance Base (ListC a) = ListF a
- Um
instance Recursive (List a) where project = ...
ich an beiden Schritte nicht zu implementieren.
Was ist Ihr Fehler? Ich habe das versucht (Hinzufügen 'newtype' für die Bequemlichkeit) und es funktioniert gut. – MigMit
Ich habe meine Frage aktualisiert – nponeccop
Der 'newtype' erwies sich als wesentlich und nicht nur als Annehmlichkeit. Der Code funktioniert jetzt. – nponeccop