该vector-0.1
包有一个非常有效的Stream
实现(Data.Vector.Stream
):
data Step s a = Yield a s
| Skip s
| Done
-- | The type of fusible streams
data Stream a = forall s. Stream (s -> Step s a) s Size
后来的版本vector
将此扩展为单子版本Data.Vector.Fusion.Stream.Monadic
,但为了简单起见,让我们使用旧的非单子版本。
Stream
很自然地是Functor
and的一个实例Foldable
:
instance Foldable Stream where
foldMap f s = foldl' (\a b -> a <> (f b)) mempty s
作为一个流,它也应该是 的一个实例Traversable
,不是吗?至少乍一看,它看起来很容易。我们需要一个
sequenceA :: Applicative f => Stream (f a) -> f (Stream a)
这将开始为
sequenceA (Stream step s) = Stream <$> step' <*> (pure s) where
step' = ...
<*>
是f
从Stream
. 现在,step'
应该
step' :: f (s -> Step s a)
我们有一个
step :: s -> Step s (f a)
我只知道这f
是一个Applicative
(和Functor
)。但是<*>
“拉入” f
(<*> :: f(a->b)->(f a->f b)
),而在这里我需要完全相反的,可以<*>
这么说。
拥有一个Traversable
实例对我的任何努力都不是至关重要的,从性能的角度来看,它甚至可能不是可取的。但让我感到困扰的是,我并没有真正理解为什么Stream
不会Traversable
。Stream
制作a缺少什么结构元素Traversable
?