Недавно смотрел на реализацию Data.Stream и увидел следующее:
data Stream a = forall s . Unlifted s => Stream !(s -> Step a s) !s
data Step a s
= Yield a !s
| Skip !s
| Done
Смысл Yield и Done вполне понятен. Но зачем Skip?
Вот, например, одна из функций:
filter :: (a -> Bool) -> Stream a -> Stream a
filter p (Stream next0 s0) = Stream next s0
where
next !s = case next0 s of
Done -> Done
Skip s' -> Skip s'
Yield x s' | p x -> Yield x s'
| otherwise -> Skip s'
Разве не проще было бы сделать так:
filter :: (a -> Bool) -> Stream a -> Stream a
filter p (Stream next0 s0) = Stream next s0
where
next !s = case next0 s of
Done -> Done
Yield x s' | p x -> Yield x s'
| otherwise -> next0 s'