在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的同时,完全按照列表进行学习是有意义的。