Changes from Stream-0.2.6 to 0.3 made by Bas van Dijk (v.dijk.bas@gmail.com):
Package changes:
* Added a TODO file.
* I incremented the major version number from 0.2.6 to 0.3 because a
lot of things changed including API changes.
* I added my name to the authors.
* I updated Stream.cabal
Note that the Stream package can handle both the old base-3.*
library as well as the new base-4.* using a cabal flag.
* I began working on a test suite in Test.hs
API changes:
* I have changed the Stream constructor to the infix ':::' instead of
'Cons' and I removed '<:>'. Just as with lists, I think it's better
to have one way to construct and deconstruct (pattern match) a
Stream. I have chosen the symbol ':::' because it resembles the List
constructor ':' and the three colons indicate that a Stream is, in a
sense, a very big list. BTW ':::' can also be typed pretty quickly.
* Stream now uses the latest QuickCheck (>= 2.1) and so has separate
instances for 'Arbitrary' and 'CoArbitrary'.
* I added a manual 'Show' instance for Streams that takes the right
associativity into account and so doesn't put parenthesis around the
tail of a Stream.
* I renamed 'scanl' and 'scanl1' to 'scan' and 'scan1' respectively
because (r)ight versions don't exist for streams so there's no need
to differentiate.
* The previous 'scanl' was to strict! I made 'scan' as lazy as its
list counterpart.
* I made 'inits' more lazy. Note that it's now lazier then
'Data.List.inits'
* 'take', 'drop' and 'splitAt' now don't fail on a negative argument
but just return the input stream. This equals the behaviour of their
list counterparts.
* I renamed 'streamToList' and 'listToStream' to 'toList' and
'fromList' respectively. The latter versions are shorter and
consistent with similar conversion functions like
'Data.Map.fromList'. Finally, given the fact that most user will
import 'Data.Stream' qualified, I think there isn't an ambiguaty.
API extensions:
* The Stream datatype now derives: 'Typeable' and 'Data' using the
'DeriveDataTypeable' extension.
* I added an 'instance MonadFix Stream'.
* I added an 'instance Foldable Stream'.
* I added an 'instance Traversable Stream'.
* Besides QuickCheck, I also use LazySmallCheck for testing so
instances for 'Serial' are added. See:
http://www.cs.york.ac.uk/fp/smallcheck/
* I implemented all functions from Data.List that make sense for
Streams:
* mapAccum :: (acc -> a -> (acc, b)) -> acc -> Stream a -> Stream b
* concat :: Stream [a] -> Stream a
* concatMap :: (a -> [b]) -> Stream a -> Stream b
* intercalate :: [a] -> Stream [a] -> Stream a
* transpose :: Stream (Stream a) -> Stream (Stream a)
* subsequences :: Stream a -> Stream [a]
* permutations :: Stream a -> Stream (Stream a)
* genericTake :: (Integral i) => i -> Stream a -> [a]
* genericDrop :: (Integral i) => i -> Stream a -> Stream a
* genericSplitAt :: (Integral i) => i -> Stream a -> ([a], Stream a)
* group :: Eq a => Stream a -> Stream [a]
* groupBy :: (a -> a -> Bool) -> Stream a -> Stream [a]
* isPrefixOf :: Eq a => [a] -> Stream a -> Bool
* stripPrefix :: Eq a => [a] -> Stream a -> Maybe (Stream a)
* genericIndex :: (Integral i) => Stream a -> i -> a
* elemIndex :: Eq a => a -> Stream a -> Int
* elemIndices :: Eq a => a -> Stream a -> Stream Int
* findIndex :: (a -> Bool) -> Stream a -> Int
* findIndices :: (a -> Bool) -> Stream a -> Stream Int
* lookup :: Eq k => k -> Stream (k, a) -> a
* zip3, zip4, zip5, zip6, zip7
* zipWith3, zipWith4, zipWith5, zipWith6, zipWith7
* unzip3, unzip4, unzip5, unzip6, unzip7
* nub :: (Eq a) => Stream a -> Stream a
* nubBy :: (a -> a -> Bool) -> Stream a -> Stream a
* delete :: (Eq a) => a -> Stream a -> Stream a
* deleteBy :: (a -> a -> Bool) -> a -> Stream a -> Stream a
* insert :: Ord a => a -> Stream a -> Stream a
* insertBy :: (a -> a -> Ordering) -> a -> Stream a -> Stream a
* I added the following functions:
* fromListCont :: [a] -> Stream a -> Stream a
* replicateCont :: Int -> a -> Stream a -> Stream a
These are handy for building streams which have a finite begin
part. (The "Cont" means "continue")
* I added the following functions from 'Data.List.Utils' from the
missingh library:
* merge :: Ord a => Stream a -> Stream a -> Stream a
* mergeBy :: (a -> a -> Ordering) -> Stream a -> Stream a -> Stream a
* I added strict versions for all recursive functions where one of the
arguments is created by a user-supplied function:
* mapAccum' :: (acc -> a -> (acc, b)) -> acc -> Stream a -> Stream b
* scan' :: (a -> b -> a) -> a -> Stream b -> Stream a
* scan1' :: (a -> a -> a) -> Stream a -> Stream a
* iterate' :: (a -> a) -> a -> Stream a
* unfold' :: (b -> (a, b)) -> b -> Stream a
* I also added the following (more obscure) functions to
Data.Stream.Utils:
* diagonal :: Stream (Stream a) -> Stream a
* diagonals :: Stream (Stream a) -> Stream [a]
* unDiagonals :: Stream [a] -> Stream (Stream a)
* concatDiagonals :: Stream (Stream a) -> Stream a
* unConcatDiagonals :: Stream a -> Stream (Stream a)
'diagonal' is used in the definiton on '>>=' (note that 'diagonal' =
'join') and 'concatDiagonals' is used in the definition of
'permutations' but I think all will be usefull in general.
* I have added the function 'fold :: (a -> b -> b) -> Stream a -> b'
* I added the module: 'Control.Monad.StreamT' providing a stream monad
transformer.
The implementation was inspired by:
http://www.haskell.org/haskellwiki/ListT_done_right_alternative
It exports the same functions as Data.Stream and where possible it
exports monadic variants of the same functions.
Internal refactoring:
* Most functions are rewritten in terms of 'fold'. This resulted
in shorter definitions which are, in most cases, easier to reason
about.
Writing functions in terms of 'fold' will also make it easier to add
fusion rules similar to the list fusion rules "fold/build",
"fold/augment", etc. which I hope to add in a later version.
* I reorganised the module a bit and changed and added documentation.
* To increase performance, all explicit recursive functions which are
applied to a non changing argument are rewritten such that the non
changing argument is bound in a closure so doesn't need to get
passed.
For example:
> iterate f x = x ::: iterate f (f x)
is rewritten to:
> iterate f = iterate_f where iterate_f x = x ::: iterate_f (f x)
or for example:
> repeat x = x :::: repeat x
is rewritten to:
> repeat x = repeat_x where repeat_x = x ::: repeat_x