Если вы хотите вытащить элемент из структуры данных, вы должны указать его индекс. Но значение индекса зависит от самой структуры данных.Индексирование в контейнеры: математические основы
class Indexed f where
type Ix f
(!) :: f a -> Ix f -> Maybe a -- indices can be out of bounds
Например ...
Элементы в списке имеют числовые позиции.
data Nat = Z | S Nat
instance Indexed [] where
type Ix [] = Nat
[] ! _ = Nothing
(x:_) ! Z = Just x
(_:xs) ! (S n) = xs ! n
Элементы в двоичном дереве идентифицируются последовательностью направлений.
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
Ищет что-то в розовом дереве влечет за собой уйдя уровни один за один раз, выбрав дерево из леса на каждом уровне.
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)
Кажется, что индекс типа продукта является сумма (говорят вам, который рука продукта смотреть), индекс элемента является типом блока, а индекс вложенного типа продукт (рассказывающий, где искать вложенный тип). Суммы, кажется, единственные, которые никак не связаны с derivative. Индекс суммы также является суммой - он сообщает вам, какая часть суммы, которую пользователь надеется найти, и если это ожидание нарушено, вы останетесь с горсткой Nothing
.
Фактически у меня был некоторый успех, реализующий !
в общем случае для функторов, определяемых как неподвижная точка полиномиального бифунтера. Я не буду вдаваться в подробности, но Fix f
можно сделать экземпляр Indexed
когда f
является экземпляром 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
... и оказывается, можно определить экземпляр Indexed2
для каждого бифункциональных строительных блоков.
Но что же происходит? Какова основная взаимосвязь между функтором и его индексом? Как это связано с производной функтора? Нужно ли понимать theory of containers (чего я не знаю), чтобы ответить на этот вопрос?
Я не думаю, что списки индексируются по номерам (это 'Nothing' довольно некрасиво). Мне список «xs» индексируется либо «Fin (length xs)», либо что-то вроде [this] (http://lpaste.net/160209). Тогда индексы являются просто позициями в соответствующем контейнере. Для списков 'Shape = ℕ' и' Position = Fin', т. Е. Вы получаете точно «Fin (length xs)», так как форма списка - его длина. – user3237465