| The typical idea is that you almost always want "spine lazy" data structures. So, streams are almost always more valuable than strict lists. In my mind, I tend to think of this as being true up to the point where the size of the structure is statically known. Thus for fixed-sized vectors (or arrays), spine strictness is very important—it gives you better control over memory usage in the very least. Unfortunately, no language I know of has a good concept of "strictness polymorphism" so in Haskell you end up with duplicate implementations of Strict and Lazy data structures. This ends up being not so much duplicated code, but a whole hell of a lot of duplicated API. And I think the stream-cons/cons distinction is trivial. It's a lack of proper polymorphism that you're dealing with there and that can be easily implemented in any language with good polymorphism. In Haskell we have a very nice (very nice if you tolerate lenses, anyway, which you should) interface called Cons which is an elaboration of class Cons s where
type Elem s
_Cons :: Prism s (Elem s, s)
which works like this instance Cons [a] where
type Elem [a] = a
_Cons = ... -- more complex than worth explaining
instance Cons (Stream a) where
type Elem (Stream a) = a
_Cons = ...
and then gives you cons :: Cons s => Elem s -> s -> s
uncons :: Cons s => s -> Maybe (Elem s, s)
which are generic in Stream a and [a]. |