如何改变在CPS风格函数传递的矢量


{-# 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功能以提高效率,但我遇到了瓶颈。

如果Attoparsec不是使用CPS编写的,我可以使用功能展开,但这不是这里的选项。问题是这里所有的调用都必须在尾部位置,没有函数返回标准意义上的东西,因此数组必须作为累加器传递。

我试图使用ST单子做到这一点,但是当它不起作用时,我尝试了上面的方法,但即使如此,它也不起作用。Haskell的类型系统真让我受不了。它是在任何可能的编辑可变数组与CPS编程时?

如果可以在ST单子内做到这一点,我将倍加感激。

告诉我使用数据结构而不是数组的帖子将被否决。

写完这篇文章几分钟后,我发现自己犯了一个语法错误。

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 $ do
                      MVec.write arr i a
                      return $ loop (i+1) arr t pos more lose_fin win_fin
                  lose t pos more _ _ =
                    Unsafe.unsafePerformIO $ do
                      x <- Vec.freeze arr
                      return $ win_fin t pos more x

以上类型检查ok。我忘了我不能在Haskell的do块之外对语句进行排序。

最新更新