Итак, я изучаю Haskell, и у меня есть красно-черное дерево с разными типами в красных и черных узлах, реализованных следующим образом:
data Rbtree a1 b1 = EmptyTree | Node a1 (Rbtree b1 a1) (Rbtree b1 a1) deriving (Show, Read, Eq)
А теперь мне нужно определить для него экземпляр функтора. Поскольку Rbtree
- это конструктор типа, который принимает два параметра, я должен создать экземпляр для Rbtree c
. И после этого я застрял. Мой код сейчас выглядит примерно так:
instance Functor (Rbtree c) where
fmap f EmptyTree = EmptyTree
fmap f (Node x left right) = Node x (fmap f left) (fmap f right)
Как вы могли догадаться, это не компилируется. (ошибки компиляции). Я понимаю, что fmap
, потому что это должно быть (a -> b) -> (Rbtree c) a -> (Rbtree c) b
, и если посмотреть глубже на Node
часть, это должно быть (a -> b) -> (Node c (Rbtree a c) (Rbree a c)) -> (Node c (Rbtree b c) (Rbree b c))
. Я не понимаю, как развернуть left
и right
, чтобы я мог применить f
только к его части. Я думаю, что мне что-то здесь не хватает.
Bifunctor
: hackage.haskell.org/package/bifunctors/ docs / Data-Bifunctor.html - person fizruk   schedule 15.05.2014data
определение красно-черного дерева не используетb1
- на самом деле у вас есть толькоa1
узлов. - person fizruk   schedule 15.05.2014EmptyTree
черный), - это то, что каждый путь содержит одинаковое количество черных узлов (поправьте меня, если я ошибаюсь). Но для этого вам понадобятся числа на уровне типа, верно? Тогда вам понадобится зависимая сумма (Σ-тип) для определенияinsert
(поскольку иногда она увеличивает это связанное число, а иногда нет). Так что я полагаю, что GADT здесь не помогут. - person fizruk   schedule 15.05.2014data MyRBTree a = forall n. MyRBTree (RBTree n a)
и определитьinsert
поверхMyRBTree
, имитируя Σ-тип, как здесь: reddit.com/r/haskell/comments/ti5il/ - person fizruk   schedule 15.05.2014