
I've noticed a few posts on the cafe, including my own experience, where the spine-strictness of the Binary instance for lists caused some confusion. I'd like to suggest an approach to preventing this confusion in the future, or at least making it easier to resolve. Having decided that it is indeed appropriate for some standard instances to be strict by default [1], I think it would be beneficial to standardize an approach for expressing that a lazy instance is expected. I propose the following newtype be added to Data.Binary. A demonstration immediately follows.
newtype Lazily a = Lazily { unLazily :: a }
-- example instance instance Binary a => Binary (Lazily [a]) where -- lazy get and put
Now
[1..] = (unLazily . decode . encode . Lazily) [1..]
instead of
_|_ = (decode . encode) [1..]
This email is a request for comments on this concept. I think it is a minimal way of expressing the intent that the serialisation be lazy [2]. Please share any concerns or suggestions. I'll submit a patch once the discussion is complete... or if it becomes inactive ;) Thanks for your time, Nick 1 - One solution is to make all standard Binary instances lazy wherever possible, but I presume that in most cases it's not needed and the compactness gained through default strictness (such as the [] instance) is quite significant. 2 - A more involved option is to recognize that serialisation always maps to a sequence, and so create another standard data type and class.
data Chunks a = Empty | Chunk !a (Chunks a) -- a la lazy bytestrings
instance Binary a => Binary (Chunks a) where -- lazy put and get
class Chunky a chunk | a -> chunk where toChunks :: a -> Chunks chunk fromChunks :: Chunks chunk -> a
All of this machinery, however, may prematurely emphasize problem-specific concerns. Thus it obfuscates the point: we just want sufficient laziness. Whatever ends up happening, the Chunks data type may be a route so common for Lazily instances that it makes sense to provide it in a library (? http://hackage.haskell.org/cgi-bin/hackage-scripts/package/strict-0.2).