为什么Applicative-traverse数组不可能? (或者是吗?)

时间:2017-01-19 13:40:07

标签: performance haskell monads unboxing

在考虑如何最好地映射(traversea -> Maybe a - Kleisli而不是unboxed vector时,我寻找了一个现有的实现。显然U.Vector不是Traversable,而是it does supply a mapMMaybe当然可以正常工作。

但问题是:真的需要Monad约束吗?好吧,事实证明,即使是boxed vectors cheat for the Traversable instance:它们实际上只是遍历一个列表,它们从/转换为:

instance Traversable.Traversable Vector where
  {-# INLINE traverse #-}
  traverse f xs = Data.Vector.fromList Applicative.<$> Traversable.traverse f (toList xs)

mono-traversable does the same thing also for unboxed vectors;在这里,这似乎更加令人毛骨悚然。

现在,如果vector实际上能够将这些被攻击的遍历融合成更有效的形式,我不会感到惊讶,但仍然 - 似乎存在根本问题,阻止我们立即在阵列上实现遍历。这种无能是否存在“深层原因”?

1 个答案:

答案 0 :(得分:2)

在阅读vector的相关来源并尝试mapMApplicative合作后,我认为Data.Vector.Unboxed.Vector没有traverse :: (Applicative f, Unbox a, Unbox b) -> (a -> f b) -> Vector a -> f (Vector b)的原因} function和Data.Vector.Vector没有原生traverse是融合代码。罪犯是以下Stream类型:

-- Data/Vector/Fusion/Stream/Monadic.hs  Line: 137

-- | Result of taking a single step in a stream
data Step s a where
  Yield :: a -> s -> Step s a
  Skip  :: s -> Step s a
  Done  :: Step s a

-- | Monadic streams
data Stream m a = forall s. Stream (s -> m (Step s a)) s

这在内部用于实现mapMm与您对Data.Vector.Unboxed.mapM的初次调用相同。但是因为此流的主干位于m仿函数内部,所以如果您只有m的应用,则无法使用它。

请参阅vector GitHub回购中的此问题:Weaken constraint on mapM

免责声明:我真的不知道融合是如何运作的。我不知道vector是如何运作的。