我听说过这种结构,它被粗略地描述为“以数据表示的遍历,应用于某个结构,而无需应用”
它可以定义为:
data X a b r =
| Done r
| Step a (X a b (b -> r))
单词描述如下:
X a b r
描述了结构的形状a
类型的事物a
,您都有机会产生b
类型的东西a
都这样做,r
。因此,列表“ {遍历”” [a]
的类型为X a b [b]
,因为如果您可以将列表的每个a
转换为b
,则可以[b]
。
我的问题是:这个东西叫什么?是否有关于它的更多信息的参考?
用法示例:
instance Functor (X a b) where
fmap f (Done r) = f r
fmap f (Step a next) = Step a (fmap (f .) next)
f :: [a] -> X a b [b]
f [] = Done []
f (a:as) = Step a (fmap (flip (:)) as)
g :: Applicative f => (a -> f b) -> X a b r -> f r
g f (Done r) = pure r
g f (Step a next) = g f next <*> f a
更一般地:
instance Applicative (X a b) where
pure x = Done x
Done f <*> y = fmap (\y -> f y) y
Step a next <*> y = Step a (fmap flip next <*> y)
t :: Traversable t => t a -> X a b (t b)
t = traverse (\a -> Step a (Done id))
而且,假设我没有犯任何错误,我们应该发现:
flip g . t == traverse
编辑:我已经考虑了更多。 traversal
所没有的东西:traversal
可以将计算拆分为“一次”的东西,例如遍历一个可以“并行”遍历左右一半。这是一种我认为具有相同效果的结构:
data Y a b r =
| Done r
| One a (b -> r)
| forall s t. Split (Y a b s) (Y a b t) (s -> t -> r)
(语法有点模糊,因为我不记得了,也不想将其写为gadt)
f1 :: X a b r -> Y a b r
f1 (Done x) = Done x
f1 (Step a next) = Split (One a id) (f1 next) (flip ($))
f2 :: Y a b r -> X a b r
f2 (Done x) = Done x
f2 (One a f) = Step a (Done f)
f2 (Split x y f) = f <$> f2 x <*> f2 y