1
{-# 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"

我正在尝试Vector在 Attoparsec 中添加一些功能以提高效率,但我遇到了麻烦。

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

我尝试使用 ST monad 来做到这一点,但是当那不起作用时,我尝试了上述方法,但即便如此它也无法正常工作。Haskell 的类型系统在这里真的要了我的命。在使用 CPS 编程时是否可以编辑可变数组?

如果可以在 ST monad 中做到这一点,我将倍加感激。

但是,告诉我使用数组以外的数据结构的帖子将被否决。

4

1 回答 1

0

在我发表这篇文章几分钟后,我突然想到我犯了一个语法错误。

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

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

于 2016-08-13T13:33:11.207 回答