The difference is in the API to the end user. If we think of a `Stream` as a `hd : Stream a -> a` and a `tl : Stream a -> Stream a` then a `Stream (Lazy a)` pops out `Lazy a`s under `hd`, meaning the end user will then have to `force`/`run` that value after they apply `hd`. I think the end user might want lazy `hd` and the people that could just as easily use strict `hd` aren't really affected.

So there are 2 arguments against `cons`. One is that it means you have a strict `hd` and the other is more philosophical: data is defined by constructors that build values and codata is defined by destructors with which you can observe pieces of the structure. Here's the paper that inspired me to write this `Stream`s library the way I did http://www2.tcs.ifi.lmu.de/~abel/popl13.pdf It's a surprisingly easy read and the first couple pages explain this view of codata. The way they used records to define codata and variants to define data makes a lot of sense to me (though in that paper there is a semantic difference as records are lazy) and I wanted to see how nice it would fit with elm records. I didn't see a good reason to change the semantics of Elm records but I like the style of implementing codata as records.