Haskell 是否有更严格的数据顺序?
下面的示例显示了Haskell 是否有更严格的数据顺序?,haskell,data-structures,sequence,lazy-evaluation,Haskell,Data Structures,Sequence,Lazy Evaluation,下面的示例显示了Data.Sequence的一个问题: {-# LANGUAGE BangPatterns #-} module Main where import qualified Data.Sequence as S import Data.Sequence ((|>), ViewL(..)) import Data.List (foldl') import GHC.AssertNF update !init !x = init |> x main = do let
Data.Sequence的一个问题:
{-# LANGUAGE BangPatterns #-}
module Main where
import qualified Data.Sequence as S
import Data.Sequence ((|>), ViewL(..))
import Data.List (foldl')
import GHC.AssertNF
update !init !x = init |> x
main =
do let !seq = foldl' update S.empty [1..10]
assertNF seq
它打印
Parameter not in normal form: 1 thunks found:
Deep (One (S# 1)) (_thunk (Deep (One ...) (_thunk ... ... ... ...) (Three ... ... ...) 93) (S# 95) (S# 96) (S# 97)) (Three (S# 98) (S# 99) (S# 100)) 100
然而,Data.Sequence
的文档声称所有的操作都是严格的,那么为什么在插入之后树没有被完全评估呢?是否需要保证某些非摊销复杂性界限
我们不太喜欢这里的懒惰,所以我想知道是否有更严格的
或类似的数据结构支持后面追加和前面枚举,可能更有效?data.Sequence是一个元素严格、数字严格的数据结构,具有懒惰的脊椎
data FingerTree a
= Empty
| Single a
| Deep {-# UNPACK #-} !Int !(Digit a) (FingerTree (Node a)) !(Digit a)
这意味着插入的值将被存储并计算,但结构的脊椎将仅在查询时计算。
这通常是您想要的--更小的数据结构
如果您想在其上强制使用一个严格的脊椎,您将承担更大的插入成本,但您可能会在其他地方获益
尝试将fingertrees包修改为spine-strict,看看它是否真的更快——我很想知道结果
顺便说一句:“我们不太喜欢这里的懒惰”,这不是避免脊椎懒惰数据结构的好理由。如果[a]是严格的,那么它将是一种糟糕的数据类型。Data.Sequence可能也是如此。您应该量化为什么脊椎狭窄对于您的用例来说是错误的语义。手指树的良好性能取决于懒惰。引自:
。。。
虽然这种结构基本上利用了懒惰,但它也是合适的
对于提供惰性求值原语的严格语言
在分析其特性时:
…因此,在一系列操作中,平均成本是恒定的
如果使用挂起子树,则在持久设置中保持相同的边界
惰性评估。这可确保脊椎深处的变换不会发生变化
直到后续操作需要进行到那个程度。因为
上述安全和危险数字的属性,到那时就足够了
为了支付这一昂贵的费用,将进行廉价的浅层作业
评估
因此,如果将实现从lazy更改为strict,可能会失去良好的时间复杂度界限(取决于您使用的操作和顺序)。“我们不太喜欢这里的惰性”。。。您可能使用了错误的语言:)@singpolyma:事实上,Haskell对我们非常有效:)从数据数字a=1A | 2A | 3A | 4A
。同样来自于在ghci中玩:length$Seq.singleton未定义--1
。而且单个a
没有代码>在它旁边。所以看起来像是数据。序列不是严格的元素。