on master help sign in
Merge pull request #383 from maxsnew/lazy
91007fcEvan Czaplicki
libraries/Lazy/Stream.elm+43
@@ -3,6 +3,7 @@ module Lazy.Stream ( head, tail
3 , map, apply, zip, zipWith, scanl
3 , map, apply, zip, zipWith, scanl
4 , take, drop, splitAt
4 , take, drop, splitAt
5 , sampleOn
5 , sampleOn
6+ , filter, takeWhile, dropWhile, splitWhen
6 ) where
7 ) where
7
8
8{-| Library for Infinite Streams
9{-| Library for Infinite Streams
@@ -16,6 +17,9 @@ module Lazy.Stream ( head, tail
16# Transform
17# Transform
17@docs map, apply, zip, zipWith, scanl
18@docs map, apply, zip, zipWith, scanl
18
19
20+# Converge
21+@docs filter, takeWhile, dropWhile, splitWhen
22+
19-}
23-}
20
24
21import Basics ((.), (<|), (-), id, fst, snd)
25import Basics ((.), (<|), (-), id, fst, snd)
@@ -123,3 +127,42 @@ splitAt n xs = case n of
123sampleOn : Signal b -> Stream a -> Signal a
127sampleOn : Signal b -> Stream a -> Signal a
124sampleOn sig str = let tails = foldp (\_ -> tail) str sig in
128sampleOn sig str = let tails = foldp (\_ -> tail) str sig in
125 head <~ tails
129 head <~ tails
130+
131+{-| Filter the elements of a Stream according to a predicate.
132+ The produced Stream will go into an infinite loop under head or tail
133+ unless there are infinitely many terms in the Stream that satisfy the
134+ predicate.
135+-}
136+filter : (a -> Bool) -> Stream a -> Stream a
137+filter p xs = cons' <| (\() ->
138+ let (hd, tl) = unS xs in
139+ case p hd of
140+ True -> (hd, filter p tl)
141+ False -> unS <| filter p tl)
142+
143+{-| Take the longest prefix of a Stream for which a predicate holds on every element.
144+ This function only terminates if there is an element of the stream for
145+ which the predicate does not hold.
146+-}
147+takeWhile : (a -> Bool) -> Stream a -> [a]
148+takeWhile p xs = fst <| splitWhen p xs
149+
150+{-| Take the first tail of a Stream for which a predicate does not
151+ hold on its head. This function only terminates if there is an element
152+ of the stream for which the predicate does not hold.
153+-}
154+dropWhile : (a -> Bool) -> Stream a -> Stream a
155+dropWhile p xs = snd <| splitWhen p xs
156+
157+{-| Split a Stream into its longest prefix for which a predicate holds and
158+ the rest of the Stream. This function only terminates if there is an element
159+ of the stream for which the predicate does not hold.
160+
161+ splitWhen p xs == (takeWhile p xs, dropWhile p xs)
162+-}
163+splitWhen : (a -> Bool) -> Stream a -> ([a], Stream a)
164+splitWhen p xs = let (hd, tl) = unS xs in
165+ case p hd of
166+ True -> let (taken, dropped) = splitWhen p tl
167+ in (hd :: taken, dropped)
168+ False -> ([], xs)