1
import Foundation
2

3
/// Traverse provides a type with the ability to traverse a structure with an effect.
4
public protocol Traverse: Functor, Foldable {
5
    /// Maps each element of a structure to an effect, evaluates them from left to right and collects the results.
6
    ///
7
    /// - Parameters:
8
    ///   - fa: A structure of values.
9
    ///   - f: A function producing an effect.
10
    /// - Returns: Results collected under the context of the effect provided by the function.
11
    static func traverse<G: Applicative, A, B>(_ fa: Kind<Self, A>, _ f: @escaping (A) -> Kind<G, B>) -> Kind<G, Kind<Self, B>>
12
}
13

14
public extension Traverse {
15
    /// Evaluate each effect in a structure of values and collects the results.
16
    ///
17
    /// - Parameter fga: A structure of values.
18
    /// - Returns: Results collected under the context of the effects.
19 0
    static func sequence<G: Applicative, A>(_ fga: Kind<Self, Kind<G, A>>) -> Kind<G, Kind<Self, A>> {
20 0
        return traverse(fga, id)
21
    }
22
}
23

24
public extension Traverse where Self: Monad {
25
    /// A traverse followed by flattening the inner result.
26
    ///
27
    /// - Parameters:
28
    ///   - fa: A structure of values.
29
    ///   - f: A transforming function yielding nested effects.
30
    /// - Returns: Results collected and flattened under the context of the effects.
31 0
    static func flatTraverse<G: Applicative, A, B>(_ fa: Kind<Self, A>, _ f: @escaping (A) -> Kind<G, Kind<Self, B>>) -> Kind<G, Kind<Self, B>> {
32 0
        return G.map(traverse(fa, f), Self.flatten)
33
    }
34
}
35

36
// MARK: Syntax for Traverse
37

38
public extension Kind where F: Traverse {
39
    /// Maps each element of this structure to an effect, evaluates them from left to right and collects the results.
40
    ///
41
    /// - Parameters:
42
    ///   - f: A function producing an effect.
43
    /// - Returns: Results collected under the context of the effect provided by the function.
44 1
    func traverse<G: Applicative, B>(_ f: @escaping (A) -> Kind<G, B>) -> Kind<G, Kind<F, B>> {
45 1
        return F.traverse(self, f)
46
    }
47

48
    /// Evaluate each effect in this structure of values and collects the results.
49
    ///
50
    /// - Returns: Results collected under the context of the effects.
51 0
    func sequence<G: Applicative, AA>() -> Kind<G, Kind<F, AA>> where A == Kind<G, AA>{
52 0
        return F.sequence(self)
53
    }
54
}
55

56
public extension Kind where F: Traverse & Monad {
57
    /// A traverse followed by flattening the inner result.
58
    ///
59
    /// - Parameters:
60
    ///   - f: A transforming function yielding nested effects.
61
    /// - Returns: Results collected and flattened under the context of the effects.
62 0
    func flatTraverse<G: Applicative, B>(_ f: @escaping (A) -> Kind<G, Kind<F, B>>) -> Kind<G, Kind<F, B>> {
63 0
        return F.flatTraverse(self, f)
64
    }
65
}

Read our documentation on viewing source code .

Loading