The usual assumption for pure data structures in Haskell is that the documented time bounds may be amortized, but that amortization must hold up under persistent use. That is not true for dlist. snoc and head are both documented as being O(1), and yet the following program runs far longer than I would ever want to wait. Swapping in Data.Sequence for DList lets this run quickly.
import qualified Data.DList as D
import Data.DList (DList)
import Data.Foldable
blob :: DList Int
blob = foldl' D.snoc mempty [1..10^7]
main :: IO ()
main = print $ sum [ D.head (blob `D.snoc` a) | a <- [1..10^6 :: Int]]
I think the best approach is likely to document that DLists are intended to be used in an affine/linear fashion, and that the bounds are only valid in that context.
The usual assumption for pure data structures in Haskell is that the documented time bounds may be amortized, but that amortization must hold up under persistent use. That is not true for
dlist.snocandheadare both documented as beingO(1), and yet the following program runs far longer than I would ever want to wait. Swapping inData.SequenceforDListlets this run quickly.I think the best approach is likely to document that
DLists are intended to be used in an affine/linear fashion, and that the bounds are only valid in that context.