在Haskell中使用Data.Sequence

在Haskell中使用Data.Sequence,haskell,Haskell,我写了一个程序,结果证明使用列表太慢了,所以我尝试切换到序列。但是,在查看文档后,我似乎无法找出正确的语法 到目前为止,我正在尝试使用以下简单代码学习: import Control.Monad import qualified Data.Sequence as S main :: IO () main = do let testSeq = S.empty testSeq S.|> 5 testSeq S.|> 20 tes

我写了一个程序,结果证明使用列表太慢了,所以我尝试切换到序列。但是,在查看文档后,我似乎无法找出正确的语法

到目前为止,我正在尝试使用以下简单代码学习:

import Control.Monad
import qualified Data.Sequence as S

main :: IO ()
main = do 
       let testSeq = S.empty
       testSeq S.|> 5
       testSeq S.|> 20
       testSeq S.|> 3
       let newSeq = S.update 2 3 testSeq
       let x = lookup 2 testSeq
       print x
我已经使用了一段时间的语法,但运气不好,但它仍然有很多错误:

test.hs:9:8:
    Couldn't match expected type ‘IO a0’
                with actual type ‘S.Seq Integer’
    In a stmt of a 'do' block: testSeq S.|> 5
    In the expression:
      do { let testSeq = S.empty;
           testSeq S.|> 5;
           testSeq S.|> 20;
           testSeq S.|> 3;
           .... }
    In an equation for ‘main’:
        main
          = do { let testSeq = ...;
                 testSeq S.|> 5;
                 testSeq S.|> 20;
                 .... }

test.hs:10:8:
    Couldn't match expected type ‘IO a1’
                with actual type ‘S.Seq Integer’
    In a stmt of a 'do' block: testSeq S.|> 20
    In the expression:
      do { let testSeq = S.empty;
           testSeq S.|> 5;
           testSeq S.|> 20;
           testSeq S.|> 3;
           .... }
    In an equation for ‘main’:
        main
          = do { let testSeq = ...;
                 testSeq S.|> 5;
                 testSeq S.|> 20;
                 .... }

test.hs:11:8:
    Couldn't match expected type ‘IO a2’
                with actual type ‘S.Seq Integer’
    In a stmt of a 'do' block: testSeq S.|> 3
    In the expression:
      do { let testSeq = S.empty;
           testSeq S.|> 5;
           testSeq S.|> 20;
           testSeq S.|> 3;
           .... }
    In an equation for ‘main’:
        main
          = do { let testSeq = ...;
                 testSeq S.|> 5;
                 testSeq S.|> 20;
                 .... }

test.hs:13:25:
    Couldn't match expected type ‘[(Integer, b)]’
                with actual type ‘S.Seq a3’
    Relevant bindings include x :: Maybe b (bound at test.hs:13:12)
    In the second argument of ‘lookup’, namely ‘testSeq’
    In the expression: lookup 2 testSeq

我是Haskell的新成员,因此非常感谢您的帮助

与Haskell中的几乎所有内容一样,
Seq
是一个纯功能数据结构。它不像是一个命令式堆栈,你把东西推到其中,改变原始结构。相反,与普通列表一样,您只需生成包含额外元素的新容器值,但这不会以任何方式影响旧的较短序列。所以,你所问的计划应该是

testSeq :: S.Seq Int
testSeq = S.update 2 3 $ S.empty S.|> 5 S.|> 20 S.|> 30

main :: IO ()
main = print $ S.lookup 2 testSeq
(它必须是,或者相当于
S.!?
。它本身就是一个在普通列表上工作的函数!)

请注意,这并没有给你带来任何优势

testSeq = S.update 2 3 $ S.fromList [5,20,30]

事实上,列表通常比
Seq
快,它们只是不允许有效的随机访问。

与Haskell中的几乎所有内容一样,
Seq
是一个纯粹的功能数据结构。它不像是一个命令式堆栈,你把东西推到其中,改变原始结构。相反,与普通列表一样,您只需生成包含额外元素的新容器值,但这不会以任何方式影响旧的较短序列。所以,你所问的计划应该是

testSeq :: S.Seq Int
testSeq = S.update 2 3 $ S.empty S.|> 5 S.|> 20 S.|> 30

main :: IO ()
main = print $ S.lookup 2 testSeq
(它必须是,或者相当于
S.!?
。它本身就是一个在普通列表上工作的函数!)

请注意,这并没有给你带来任何优势

testSeq = S.update 2 3 $ S.fromList [5,20,30]

事实上,列表通常比
Seq
快,它们只是不允许有效的随机访问。

你如何对列表做同样的事情?试图强迫Haskell程序进入其他语言的“语句序列”模型通常不会找到一个好位置。你上次的编辑完全改变了这个问题,请不要这样做。您将如何处理列表?尝试将Haskell程序强制到其他语言的“语句序列”模型中通常不会找到一个好位置。您上次的编辑完全改变了问题,请不要这样做。谢谢!这是有道理的。但是,在S.lookup上,我得到了一个不在范围内的错误。我在编辑的问题代码中得到了相同的答案(很抱歉)。嗯,你使用的是什么版本的软件包?(
cabal info containers
lookup
最近才被添加到
Sequence
模块(0.5.8)中,之前它只有一个,您也可以使用它(但它没有安全长度检查)。这仍然感觉像是一个x/y问题。如果@Strobe00希望快速随机访问/更新有序集合中的元素,那么映射结构可能会更好地为它们提供服务。@ThomasM.DuBuisson我最后选择了IO数组,现在速度要快得多。@Strobe00尽管在某些使用情况下,可变数组比任何其他方法都能提供更好的性能,我建议您仅将其用作最后的优化手段。许多算法只需使用纯功能性工具(我敢说,如果包含不可变压缩向量,大多数工具)就可以同样有效地实现,只有这样,您才能真正从Haskell的强大安全保证中获益。在可变数组中使用Haskell更像是用不必要的笨拙语法编写C。特别是,在学习Haskell的同时,完全按照列表来感受它是有意义的。谢谢!这是有道理的。但是,在S.lookup上,我得到了一个不在范围内的错误。我在编辑的问题代码中得到了相同的答案(很抱歉)。嗯,你使用的是什么版本的软件包?(
cabal info containers
lookup
最近才被添加到
Sequence
模块(0.5.8)中,之前它只有一个,您也可以使用它(但它没有安全长度检查)。这仍然感觉像是一个x/y问题。如果@Strobe00希望快速随机访问/更新有序集合中的元素,那么映射结构可能会更好地为它们提供服务。@ThomasM.DuBuisson我最后选择了IO数组,现在速度要快得多。@Strobe00尽管在某些使用情况下,可变数组比任何其他方法都能提供更好的性能,我建议您仅将其用作最后的优化手段。许多算法只需使用纯功能性工具(我敢说,如果包含不可变压缩向量,大多数工具)就可以同样有效地实现,只有这样,您才能真正从Haskell的强大安全保证中获益。在可变数组中使用Haskell更像是用不必要的笨拙语法编写C。特别是,在学习Haskell的同时,完全按照列表进行学习是有意义的。