Ответ 1
Вы только что обнаружили comonads! Ну, почти.
class Functor f => Comonad f where
extract :: f a -> a
duplicate :: f a -> f (f a)
instance Comonad Tree where
extract (Node x _ _) = x -- this one only works if your trees are guaranteed non-empty
duplicate [email protected](Node n b1 b2) = Node t (duplicate b1) (duplicate b2)
С помощью duplicate
вы можете реализовать свои функции:
treeMap f = fmap f . duplicate
freeFold f i = foldr f i . duplicate
Чтобы сделать это правильно, вы должны обеспечить непустоту системой типов:
type Tree' a = Maybe (Tree'' a)
data Tree'' t = Node' t (Tree' t) (Tree' t)
deriving (Functor)
instance Comonad Tree'' where
extract (Node' x _ _) = x
duplicate [email protected](Node' _ b1 b2) = Node' t (fmap duplicate b1) (fmap duplicate b2)