3 ms·
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
by tel 12y ago
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].