Wenn Sie ein Element aus einer Datenstruktur ziehen möchten, müssen Sie seinen Index angeben. Aber die Bedeutung von Index hängt von der Datenstruktur selbst ab.Indizierung in Container: die mathematischen Grundlagen
class Indexed f where
type Ix f
(!) :: f a -> Ix f -> Maybe a -- indices can be out of bounds
Zum Beispiel ...
Elemente in einer Liste finden numerische Positionen.
Elemente in einem binären Baum werden durch eine Abfolge von Richtungen identifiziert.
data Tree a = Leaf | Node (Tree a) a (Tree a)
data TreeIx = Stop | GoL TreeIx | GoR TreeIx -- equivalently [Bool]
instance Indexed Tree where
type Ix Tree = TreeIx
Leaf ! _ = Nothing
Node l x r ! Stop = Just x
Node l x r ! GoL i = l ! i
Node l x r ! GoR j = r ! j
die Suche nach etwas in einem Rosenbaum bringt auf jeder Ebene, indem Sie einen Baum aus dem Wald zu einer Zeit, die Ebenen einen Rücktritt.
data Rose a = Rose a [Rose a] -- I don't even like rosé
data RoseIx = Top | Down Nat RoseIx -- equivalently [Nat]
instance Indexed Rose where
type Ix Rose = RoseIx
Rose x ts ! Top = Just x
Rose x ts ! Down i j = ts ! i >>= (! j)
Es scheint, dass der Index eines Produkttyps ist eine Summe (sagen Ihnen, welche Arm des Produkts zu sehen), der Index eines Elements ist die Art der Einheit und der Index eines verschachtelten Typs ein Produkt (sagt Ihnen, wo Sie im verschachtelten Typ suchen). Summen scheinen die einzigen zu sein, die nicht irgendwie mit dem derivative verknüpft sind. Der Index einer Summe ist auch eine Summe - er sagt Ihnen, welcher Teil der Summe der Benutzer zu finden hofft, und wenn diese Erwartung verletzt wird, bleiben Sie mit einer Handvoll Nothing
.
In der Tat hatte ich einige Erfolge bei der Implementierung !
generisch für Funktoren definiert als der Fixpunkt eines Polynoms Bifunctor. Ich werde nicht ins Detail gehen, aber Fix f
kann eine Instanz von Indexed
gemacht werden, wenn f
eine Instanz von Indexed2
ist ...
class Indexed2 f where
type IxA f
type IxB f
ixA :: f a b -> IxA f -> Maybe a
ixB :: f a b -> IxB f -> Maybe b
... und es stellt sich heraus, Sie eine Instanz von Indexed2
für jede definieren der Bifunktorfelder.
Aber was ist wirklich los? Was ist die zugrunde liegende Beziehung zwischen einem Funktor und seinem Index? Wie verhält es sich mit dem Derivat des Funktors? Muss man die theory of containers (die ich nicht wirklich verstehe) verstehen, um diese Frage zu beantworten?
Ich glaube nicht wirklich, dass die Listen von Zahlen indiziert werden (diese 'Nothing' ist ziemlich hässlich). Für mich wird eine Liste 'xs' entweder durch' Fin (Länge xs) 'oder etwas ähnliches [http://lpaste.net/160209] indiziert. Dann sind Indizes einfach Positionen im entsprechenden Container. Für Listen "Shape = ℕ" und "Position = Fin", d. H. Sie erhalten genau "Fin (Länge xs)", da die Form einer Liste ihre Länge ist. – user3237465