1
import Foundation
2

3
/// TraverseFilter represents array-like structures that can be traversed and filtered as a single combined operation. It provides the same capabilities as `Traverse` and `FunctorFilter` together.
4
public protocol TraverseFilter: Traverse, FunctorFilter {
5
    /// A combined traverse and filter operation. Filtering is handled using `Option` instead of Bool so that the output can be different than the input type.
6
    ///
7
    /// - Parameters:
8
    ///   - fa: A value in the context implementing this instance.
9
    ///   - f: A function to traverse and filter each value.
10
    /// - Returns: Result of traversing this structure and filter values using the provided function.
11
    static func traverseFilter<A, B, G: Applicative>(_ fa: Kind<Self, A>, _ f: @escaping (A) -> Kind<G, OptionOf<B>>) -> Kind<G, Kind<Self, B>>
12
}
13

14
// MARK: Related functions
15

16
public extension TraverseFilter {
17
    /// Filters values in a different context.
18
    ///
19
    /// - Parameters:
20
    ///   - fa: A value in the context implementing this instance.
21
    ///   - f: A function to filter each value.
22
    /// - Returns: Result of traversing this structure and filter values using the provided function.
23 1
    static func filterA<A, G: Applicative>(_ fa: Kind<Self, A>, _ f: @escaping (A) -> Kind<G, Bool>) -> Kind<G, Kind<Self, A>> {
24 1
        return traverseFilter(fa, { a in G.map(f(a), { b in b ? Option.some(a) : Option.none() }) })
25
    }
26

27
    /// Filters values using a predicate.
28
    ///
29
    /// - Parameters:
30
    ///   - fa: A value in the context implementing this instance.
31
    ///   - f: A boolean predicate.
32
    /// - Returns: Result of traversing this structure and filter values using the provided function.
33 0
    static func filter<A>(_ fa: Kind<Self, A>, _ f: @escaping (A) -> Bool) -> Kind<Self, A> {
34 0
        return (filterA(fa, { a in Id.pure(f(a)) })).extract()
35
    }
36
}
37

38
// MARK: Syntax for TraverseFilter
39

40
public extension Kind where F: TraverseFilter {
41
    /// A combined traverse and filter operation. Filtering is handled using `Option` instead of Bool so that the output can be different than the input type.
42
    ///
43
    /// This is a convenience method to call `TraverseFilter.traverseFilter` as an instance method of this type.
44
    ///
45
    /// - Parameters:
46
    ///   - fa: A value in this context.
47
    ///   - f: A function to traverse and filter each value.
48
    /// - Returns: Result of traversing this structure and filter values using the provided function.
49 1
    func traverseFilter<B, G: Applicative>(_ f: @escaping (A) -> Kind<G, OptionOf<B>>) -> Kind<G, Kind<F, B>> {
50 1
        return F.traverseFilter(self, f)
51
    }
52

53
    /// Filters values in a different context.
54
    ///
55
    /// This is a convenience method to call `TraverseFilter.filterA` as an instance method of this type.
56
    ///
57
    /// - Parameters:
58
    ///   - fa: A value in this context.
59
    ///   - f: A function to filter each value.
60
    /// - Returns: Result of traversing this structure and filter values using the provided function.
61 0
    func filterA<G: Applicative>(_ f: @escaping (A) -> Kind<G, Bool>) -> Kind<G, Kind<F, A>> {
62 0
        return F.filterA(self, f)
63
    }
64
}

Read our documentation on viewing source code .

Loading