{-# LANGUAGE ScopedTypeVariables,BangPatterns #-}
import qualified Data.Attoparsec.Internal as I
import qualified Data.Attoparsec.Internal.Types as T
import qualified Data.Vector.Unboxed as UVec
import qualified Data.Vector.Unboxed.Mutable as UMVec
import qualified Data.Vector as Vec
import qualified Data.Vector.Mutable as MVec
import qualified Data.Text as Text
import qualified System.IO.Unsafe as Unsafe
import Control.Monad.ST
import Control.Monad.Primitive
type Parser = T.Parser
manyCPSVec :: Parser Text.Text Char -> Parser Text.Text (Vec.Vector Char)
manyCPSVec parser = T.Parser $ \t pos more lose_fin win_fin ->
let arr = Unsafe.unsafePerformIO (MVec.new 1024) in
loop 0 arr t pos more lose_fin win_fin where
loop i (arr :: MVec.MVector RealWorld Char) t pos more lose_fin win_fin =
T.runParser parser t pos more lose win where
win t !pos more (a :: Char) =
Unsafe.unsafePerformIO (MVec.write arr i a) -- Here is the problem
loop (i+1) arr t pos more lose_fin win_fin
lose t pos more _ _ =
--x <- Vec.freeze arr
win_fin t pos more (Vec.empty)
main = print "Hello"
私は効率のためにAttoparsecにいくつかのVector
機能を入れようとしていますが、私は壁にぶつかりました。CPSスタイル関数で渡されたベクターを突然変異させる方法は?
AttoparsecがCPSを使用して書かれていない場合は、functional unfoldrを使用している可能性がありますが、これはオプションではありません。問題は、すべての呼び出しがここで末尾になければならず、関数の標準的な意味で関数が返されないため、配列をアキュムレータとして渡す必要があるということです。
私はSTモナドを使ってこれを試みましたが、それがうまくいかなかったときに私は上記を試みましたが、それでもうまくいきません。ハスケルの型システムは本当にここで私を殺しています。とにかくCPSでプログラミングするときに可変配列を編集することは可能ですか?
これをSTモナド内で実行することができれば、私はこれを二倍に感謝するでしょう。
しかし、配列以外のデータ構造を使用するように指示されている投稿は、削除されます。
これは、リストを収集し、 'Vector.fromList'を使うよりも速くなるのでしょうか? – Michael
私はあなたが 'ST'でこれを行う方法を見つけることができるはずだと思います。問題は部分的な結果を効率的に扱うことになりますが、それらを処理するための効率的な方法はないと思います。特に、部分的な結果が異なる入力で複数回再開できることを覚えていて、あまりにも多くの 'unsafePerformIO'があなたのコードを壊す可能性があります。 – dfeuer
@Michaelええ、かなり。 10Mの整数を解析する場合、使用するデータ構造に違いがあります。ボックス化されたベクトルで[完成したパーサー](https://github.com/mrakgr/futhark/blob/parser_attempts/cps_parser_v5.hs)を使用すると、7.6sの10M intを扱います。ボックス化されていないパーサーでは、4秒でそれを行います。 boxed Vectorで拡張機能unfoldrを使用するだけで、2秒で動作します。 F#の 'ResizeArray'は1.2sでそれを行います。 [persistent vector](https://hackage.haskell.org/package/persistent-vector)は9.8でそれを行います。 F#ソリューションとは別に、彼らはすべて100Mでヒープを吹き飛ばします。リストは10Mよりずっと前にそれを行います。 –