2017-01-19 9 views
10

traversea -> Maybe a -Kleisliをunboxed vector以上にマップする方法を考えながら、既存の実装を探しました。明らかにU.VectorTraversableではありませんが、Maybeはもちろん問題ありません。it does supply a mapMです。Applicative-Traverseアレイがなぜ不可能なのですか?

しかし、問題は: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-traversabledoes the same thing also for unboxed vectorsを。ここではこれはもっと悲惨なパフォーマンス志向のようです。

実際にvectorがこれらのハッキングされたトラバーサルの多くをより効率的な形に融合できたとしても、私は驚くことはありませんが、根本的な問題があると思われます。すぐに配列。この無能さに「深い理由」がありますか?

+1

'U.Vector'のインスタンスの欠如は、要素の' Unbox'制約と関係があります。 [* unboxed配列がfoldableのインスタンスではないのはなぜですか?](http://opackoverflow.com/q/36322904/2751851)(Snoymanの回答には、* mono-traversable *に関する関連コメントも含まれています)。 – duplode

+3

もちろん、それは私が求めていることではありません。実際のTraversableインスタンスは必要ありません。効率的なトラバーサルが必要です。そして、「モノトラバーシブル」はこれを提供しません。 – leftaroundabout

+0

おっと - 私はあなたの最初の段落で "明らかに"気づいていません:) – duplode

答えて

2

vectorの関連するソースを読んとApplicativemapM仕事をしようとした後、私はData.Vector.Unboxed.Vectortraverse :: (Applicative f, Unbox a, Unbox b) -> (a -> f b) -> Vector a -> f (Vector b)機能を持っており、Data.Vector.Vectorない理由は、ネイティブtraverseが融合コードではありませんと思います。これはmapMを実装するために内部的に使用されて

-- 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 

:犯罪者は、次のStreamタイプです。 mは、最初の呼び出しであるData.Vector.Unboxed.mapMと同じです。しかし、このストリームの背骨はmファンクタ内にあるため、mの申請者しかいない場合は、このストリームで作業することはできません。

vector GitHubレポ:Weaken constraint on mapMにも掲載されています。

免責事項:私は核融合の仕組みを本当に知りません。私はvectorの仕組みがわからない。

関連する問題