The splitAt
on streams that is substituted by the fusion rules (http://hackage.haskell.org/package/stream-fusion-0.1.2.5/docs/Data-Stream.html#g:12) has the following signature:
splitAt :: Int -> Stream a -> ([a], [a])
From this we can see that since it produces lists and not streams, that obstructs further fusion. The correct thing to do, I think, is to produce either a splitAt
that generates streams, or better yet to write a chunks
function directly on streams with the appropriate fusion rules from the list version.
Here is a splitAt
on streams that I think should be good. You would of course need to pair it with the appropriate rewrite rules from a splitAt
on lists, and if those rewrite rules get tricky, perhaps write the chunks
function directly, though it seems a bit tricky to do so as well:
splitAt :: Int -> Stream a -> (Stream a, Stream a)
splitAt n0 (Stream next s0)
| n0 < 0 = (nilStream, (Stream next s0))
| otherwise = loop_splitAt n0 s0
where
nilStream = Stream (const Done) s0
loop_splitAt 0 !s = (nilStream, (Stream next s))
loop_splitAt !n !s = case next s of
Done -> (nilStream, nilStream)
Skip s' -> loop_splitAt n s'
Yield x s' -> (cons x xs', xs'')
where
(xs', xs'') = loop_splitAt (n-1) s'