Haskell 如何变异CPS风格函数中传递的向量? {-#语言范围的类型变量,模式#-} 导入符合条件的Data.c.Internal作为I 将限定的Data.Attoparsec.Internal.Types导入为T 导入符合条件的Data.Vector.unbox作

Haskell 如何变异CPS风格函数中传递的向量? {-#语言范围的类型变量,模式#-} 导入符合条件的Data.c.Internal作为I 将限定的Data.Attoparsec.Internal.Types导入为T 导入符合条件的Data.Vector.unbox作,haskell,continuations,continuation-passing,Haskell,Continuations,Continuation Passing,如何变异CPS风格函数中传递的向量? {-#语言范围的类型变量,模式#-} 导入符合条件的Data.c.Internal作为I 将限定的Data.Attoparsec.Internal.Types导入为T 导入符合条件的Data.Vector.unbox作为UVec 将限定的Data.Vector.unbox.Mutable导入为UMVec 导入符合条件的数据。矢量为Vec 将限定的Data.Vector.Mutable作为MVec导入 导入符合条件的数据。文本作为文本 将合格的System.I

如何变异CPS风格函数中传递的向量?
{-#语言范围的类型变量,模式#-}
导入符合条件的Data.c.Internal作为I
将限定的Data.Attoparsec.Internal.Types导入为T
导入符合条件的Data.Vector.unbox作为UVec
将限定的Data.Vector.unbox.Mutable导入为UMVec
导入符合条件的数据。矢量为Vec
将限定的Data.Vector.Mutable作为MVec导入
导入符合条件的数据。文本作为文本
将合格的System.IO.Unsafe导入为不安全
进口管制站
导入控制.Monad.Primitive
类型Parser=T.Parser
manyCPSVec::Parser Text.Text Char->Parser Text.Text(Vec.Vector Char)
manyCPSVec parser=T.parser$\T pos more lose\u fin win\u fin->
让arr=Unsafe.unsafePerformIO(MVec.new 1024)在
循环0 arr t pos more lose\u fin win\u fin在哪里
循环i(arr::MVec.MVector RealWorld Char)t pos more lose\u fin win\u fin=
T.runParser解析器T pos更多输赢在哪里
赢!pos more(a::Char)=
Unsafe.unsafePerformIO(MVec.write arr i a)——问题出在这里
循环(i+1)到达位置更多损失\u fin赢\u fin
失去更多位置=

--写这篇文章几分钟后,我突然发现我犯了一个语法错误

{-# 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"
manyCPSVec::Parser Text.Text Char->Parser Text.Text(Vec.Vector Char)
manyCPSVec parser=T.parser$\T pos more lose\u fin win\u fin->
让arr=Unsafe.unsafePerformIO(MVec.new 1024)在
循环0 arr t pos more lose\u fin win\u fin在哪里
循环i(arr::MVec.MVector RealWorld Char)t pos more lose\u fin win\u fin=
T.runParser解析器T pos更多输赢在哪里
赢!pos more(a::Char)=
不安全。不安全性能$do
MVec.write arr i a
返回$loop(i+1)arr t pos more lose\u fin win\u fin
失去更多位置=
不安全。不安全性能$do

写这篇文章几分钟后,我突然发现我犯了一个语法错误

{-# 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"
manyCPSVec::Parser Text.Text Char->Parser Text.Text(Vec.Vector Char)
manyCPSVec parser=T.parser$\T pos more lose\u fin win\u fin->
让arr=Unsafe.unsafePerformIO(MVec.new 1024)在
循环0 arr t pos more lose\u fin win\u fin在哪里
循环i(arr::MVec.MVector RealWorld Char)t pos more lose\u fin win\u fin=
T.runParser解析器T pos更多输赢在哪里
赢!pos more(a::Char)=
不安全。不安全性能$do
MVec.write arr i a
返回$loop(i+1)arr t pos more lose\u fin win\u fin
失去更多位置=
不安全。不安全性能$do

x只是想知道,这比收集一个列表并使用
Vector.fromList
更快吗?我认为您应该能够在
ST
中找到一种方法来实现这一点。挑战在于有效地处理部分结果,但我怀疑没有完全有效的方法来处理这些结果。特别要记住,部分结果可能会使用不同的输入多次恢复,因此过多的
unsafePerformIO
可能会破坏您的代码。@Michael是的,相当多。对于解析10M个整数,您使用的数据结构会有所不同。使用装箱向量,它在7.6秒内处理10米整数。使用unbox解析器,它可以在4s内完成。仅仅使用一个扩展的函数展开器和一个装箱向量就可以在2秒内完成<代码>调整数组大小
在F中#在1.2s中完成。在9.8节中,它是这样做的。除了F#解决方案外,它们都会在100米的高度上爆炸。清单早在10米前就已经这么做了。@d老实说,我现在对这个完全失去了兴趣。实际上,我在Haskell中尝试过的任何东西都不能让我在不破坏堆的情况下解析100万个整数,而且我已经尝试了10天的各种方法。我认为这是语言的失败。我最终弄明白了CPS和Monad,但没有弄明白如何在命令式语言中完成一项需要花费我1000万美元的任务。如果你真的只是解析以空格分隔的
Int
s,我认为解析库可能太花哨了
Data.ByteString.Char8.readInt
非常快。我想知道,这比收集列表并使用
Vector.fromList
快吗?我想你应该能够在
ST
中找到一种方法来实现这一点。挑战在于有效地处理部分结果,但我怀疑没有完全有效的方法来处理这些结果。特别要记住,部分结果可能会使用不同的输入多次恢复,因此过多的
unsafePerformIO
可能会破坏您的代码。@Michael是的,相当多。对于解析10M个整数,您使用的数据结构会有所不同。使用装箱向量,它在7.6秒内处理10米整数。使用unbox解析器,它可以在4s内完成。仅仅使用一个扩展的函数展开器和一个装箱向量就可以在2秒内完成<代码>调整数组大小
在F中#在1.2s中完成。在9.8节中,它是这样做的。除了F#解决方案外,它们都会在100米的高度上爆炸。清单早在10米前就已经这么做了。@d老实说,我现在对这个完全失去了兴趣。实际上,我在Haskell中尝试过的任何东西都不能让我在不破坏堆的情况下解析100万个整数,而且我已经尝试了10天的各种方法。我认为这是语言的失败。我最终弄明白了CPS和Monad,但没有弄明白如何在命令式语言中完成一项需要花费我1000万美元的任务。如果你真的只是解析以空格分隔的
Int
s,我认为解析库可能太花哨了
Data.ByteString.Char8.readInt
速度非常快。