diff --git a/src/FSharpx.Collections/LazyList.fs b/src/FSharpx.Collections/LazyList.fs
index ab0c935f..9d7803bc 100644
--- a/src/FSharpx.Collections/LazyList.fs
+++ b/src/FSharpx.Collections/LazyList.fs
@@ -184,6 +184,27 @@ module LazyList =
| Some a -> a
| None -> indexNotFound()
+ let rec exists p s =
+ match getCell s with
+ | CellCons(a, b) -> if p a then true else exists p b
+ | CellEmpty -> false
+
+ let rec forall p s =
+ match getCell s with
+ | CellCons(a, b) -> if not(p a) then false else forall p b
+ | CellEmpty -> true
+
+ let rec choose f s1 =
+ lzy(fun () -> choosec f s1)
+
+ and choosec f s1 =
+ match getCell s1 with
+ | CellCons(a, b) ->
+ match f a with
+ | Some v -> consc v (choose f b)
+ | None -> choosec f b
+ | CellEmpty -> CellEmpty
+
let rec scan f acc s1 =
lzy(fun () ->
match getCell s1 with
diff --git a/src/FSharpx.Collections/LazyList.fsi b/src/FSharpx.Collections/LazyList.fsi
index 8c99f156..3540c24d 100644
--- a/src/FSharpx.Collections/LazyList.fsi
+++ b/src/FSharpx.Collections/LazyList.fsi
@@ -123,6 +123,16 @@ module LazyList =
/// Raise KeyNotFoundException if no such element exists.
val find: predicate: ('T -> bool) -> source: LazyList<'T> -> 'T
+ ///O(n), worst case. Returns true if any element of the list satisfies the given predicate.
+ val exists: predicate: ('T -> bool) -> source: LazyList<'T> -> bool
+
+ ///O(n), worst case. Returns true if all elements of the list satisfy the given predicate.
+ val forall: predicate: ('T -> bool) -> source: LazyList<'T> -> bool
+
+ ///O(1). Returns a new list consisting of the results of applying the given function to each element,
+ /// keeping only the values where the function returns Some.
+ val choose: mapping: ('T -> 'U option) -> source: LazyList<'T> -> LazyList<'U>
+
///O(1). Evaluates to the list that contains no items
[]
val empty<'T> : LazyList<'T>
diff --git a/tests/FSharpx.Collections.Tests/LazyListTests.fs b/tests/FSharpx.Collections.Tests/LazyListTests.fs
index abdd1bdb..640b6d58 100644
--- a/tests/FSharpx.Collections.Tests/LazyListTests.fs
+++ b/tests/FSharpx.Collections.Tests/LazyListTests.fs
@@ -532,4 +532,57 @@ module LazyList =
}
test "scan 3" { Expect.equal "scan" [ 0; 1; 3 ] (LazyList.scan (+) 0 (LazyList.ofList [ 1; 2 ]) |> LazyList.toList) }
- test "scan 0" { Expect.equal "scan" [ 0 ] (LazyList.scan (+) 0 (LazyList.ofList []) |> LazyList.toList) } ]
+ test "scan 0" { Expect.equal "scan" [ 0 ] (LazyList.scan (+) 0 (LazyList.ofList []) |> LazyList.toList) }
+
+ test "exists returns true when element satisfies predicate" {
+ let ll = LazyList.ofList [ 1; 2; 3; 4; 5 ]
+ Expect.isTrue "exists" (LazyList.exists (fun x -> x = 3) ll)
+ }
+
+ test "exists returns false when no element satisfies predicate" {
+ let ll = LazyList.ofList [ 1; 2; 3; 4; 5 ]
+ Expect.isFalse "exists" (LazyList.exists (fun x -> x = 6) ll)
+ }
+
+ test "exists empty returns false" { Expect.isFalse "exists empty" (LazyList.exists (fun _ -> true) LazyList.empty) }
+
+ test "forall returns true when all elements satisfy predicate" {
+ let ll = LazyList.ofList [ 2; 4; 6; 8 ]
+ Expect.isTrue "forall" (LazyList.forall (fun x -> x % 2 = 0) ll)
+ }
+
+ test "forall returns false when some element does not satisfy predicate" {
+ let ll = LazyList.ofList [ 2; 3; 4 ]
+ Expect.isFalse "forall" (LazyList.forall (fun x -> x % 2 = 0) ll)
+ }
+
+ test "forall empty returns true" { Expect.isTrue "forall empty" (LazyList.forall (fun _ -> false) LazyList.empty) }
+
+ test "choose keeps Some values in order" {
+ let ll = LazyList.ofList [ 1; 2; 3; 4; 5 ]
+ let result = LazyList.choose (fun x -> if x % 2 = 0 then Some(x * 10) else None) ll
+ Expect.equal "choose" [ 20; 40 ] (LazyList.toList result)
+ }
+
+ test "choose all None returns empty" {
+ let ll = LazyList.ofList [ 1; 3; 5 ]
+ let result = LazyList.choose (fun _ -> None) ll
+ Expect.isTrue "choose none" (LazyList.isEmpty result)
+ }
+
+ test "choose lazy: only evaluates up to consumed elements" {
+ let counter = ref 0
+
+ let ll =
+ LazyList.ofSeq(
+ seq {
+ for i in 1..10 do
+ incr counter
+ yield i
+ }
+ )
+
+ let chosen = LazyList.choose (fun x -> if x % 2 = 0 then Some x else None) ll
+ let first = LazyList.head chosen
+ Expect.equal "choose lazy first" 2 first
+ } ]