Jeśli chcesz wyciągnąć element ze struktury danych, musisz podać jego indeks. Ale znaczenie tego parametru zależy od samej struktury danych.Indeksowanie w kontenerach: podstawy matematyczne
class Indexed f where
type Ix f
(!) :: f a -> Ix f -> Maybe a -- indices can be out of bounds
Na przykład ...
Elementy na liście mają pozycji numerycznych.
data Nat = Z | S Nat
instance Indexed [] where
type Ix [] = Nat
[] ! _ = Nothing
(x:_) ! Z = Just x
(_:xs) ! (S n) = xs ! n
Elementy w drzewie binarnym są identyfikowane za pomocą sekwencji wskazówek.
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
Szukasz czegoś w drzewa różanego wiąże ustąpię poziomy jeden na raz wybierając drzewo z lasu na każdym poziomie.
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)
Wydaje się, że indeks danego typu produktu to suma (z informacją, której ramię produktu patrzeć), indeks elementu jest typ jednostki, a indeks typu zagnieżdżonego jest produkt (informujący, gdzie szukać w typie zagnieżdżonym). Kwoty wydają się być jedynymi, które nie są w jakiś sposób powiązane z derivative. Indeks sumy jest również sumą - informuje, która część sumy, którą użytkownik ma nadzieję znaleźć, i jeśli to oczekiwanie zostanie naruszone, pozostanie ci garstka z Nothing
.
Rzeczywiście, odniosłem pewien sukces, wprowadzając generalnie !
dla funktorów zdefiniowanych jako stały punkt wielomianu dwufunkcyjnego. Nie będę wchodzić w szczegóły, ale Fix f
można instancję Indexed
gdy f
jest instancją Indexed2
...
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
... i okazuje się, można zdefiniować instancję Indexed2
dla każdego bloków konstrukcyjnych bifunctor.
Ale co się naprawdę dzieje? Jaki jest podstawowy związek między funktorem a jego indeksem? Jak to się ma do pochodnej funktora? Czy konieczne jest zrozumienie theory of containers (której tak naprawdę nie mam), aby odpowiedzieć na to pytanie?
I naprawdę nie sądzę, że listy są indeksowane według numerów (w tym 'Nothing' jest raczej brzydki). Dla mnie lista 'xs' jest indeksowana przez' Fin (długość xs) 'lub coś podobnego [this] (http://lpaste.net/160209). Następnie wskaźniki są po prostu pozycjami w odpowiednim pojemniku. Dla list 'Shape = ℕ' i' Position = Fin', tzn. Otrzymujesz dokładnie 'Fin (długość xs)', ponieważ kształt listy jest jego długością. – user3237465