树函子和可折叠但带有节点。有什么概括吗?
Tree Functor and Foldable but with Nodes. Is there any generalization over it?
data Tree t = Empty | Node t (Tree t) (Tree t)
我们可以创建 Functor 实例并使用
fmap :: (t -> a) -> Tree t -> Tree a
但是如果我想要 (Tree t -> a) 而不是 (t -> a) 那么我可以访问整个 (Node t) 而不仅仅是 t
treeMap :: (Tree t -> a) -> Tree t -> Tree a
treeMap f Empty = Empty
treeMap f n@(Node _ l r) = Node (f n) (treeMap f l) (treeMap f r)
与折叠相同
treeFold :: (Tree t -> a -> a) -> a -> Tree t -> a
是否对这些函数进行了概括?
map :: (f t -> a) -> f t -> f a
fold :: (f t -> a -> a) -> a -> f t -> a
您刚刚发现了共生体!嗯,差不多。
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 t@(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 t@(Node' _ b1 b2) = Node' t (fmap duplicate b1) (fmap duplicate b2)
data Tree t = Empty | Node t (Tree t) (Tree t)
我们可以创建 Functor 实例并使用
fmap :: (t -> a) -> Tree t -> Tree a
但是如果我想要 (Tree t -> a) 而不是 (t -> a) 那么我可以访问整个 (Node t) 而不仅仅是 t
treeMap :: (Tree t -> a) -> Tree t -> Tree a
treeMap f Empty = Empty
treeMap f n@(Node _ l r) = Node (f n) (treeMap f l) (treeMap f r)
与折叠相同
treeFold :: (Tree t -> a -> a) -> a -> Tree t -> a
是否对这些函数进行了概括?
map :: (f t -> a) -> f t -> f a
fold :: (f t -> a -> a) -> a -> f t -> a
您刚刚发现了共生体!嗯,差不多。
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 t@(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 t@(Node' _ b1 b2) = Node' t (fmap duplicate b1) (fmap duplicate b2)