1
import Foundation
2

3
/// An Invariant Functor provides a type the ability to transform its value type into another type. An instance of `Functor` or `Contravariant` are Invariant Functors as well.
4
public protocol Invariant {
5
    /// Transforms the value type using the functions provided.
6
    ///
7
    /// The implementation of this function must obey the following laws:
8
    ///
9
    ///     imap(fa, id, id) == fa
10
    ///     imap(imap(fa, f1, g1), f2, g2) == imap(fa, compose(f2, f1), compose(g2, g1))
11
    ///
12
    /// - Parameters:
13
    ///   - fa: Value whose value type will be transformed.
14
    ///   - f: Transforming function.
15
    ///   - g: Transforming function.
16
    /// - Returns: A new value in the same context as the original value, with the value type transformed.
17
    static func imap<A, B>(_ fa : Kind<Self, A>, _ f : @escaping (A) -> B, _ g : @escaping (B) -> A) -> Kind<Self, B>
18
}
19

20
// MARK: Syntax for Invariant
21

22
public extension Kind where F: Invariant {
23
    /// Transforms the value type using the functions provided.
24
    ///
25
    /// This is a conveninece method to call `Invariant.imap` as an instance method.
26
    ///
27
    /// - Parameters:
28
    ///   - f: Transforming function.
29
    ///   - g: Transforming function.
30
    /// - Returns: A new value in the same context as the original value, with the value type transformed.
31 1
    func imap<B>(_ f : @escaping (A) -> B, _ g : @escaping (B) -> A) -> Kind<F, B> {
32 1
        return F.imap(self, f, g)
33
    }
34
}

Read our documentation on viewing source code .

Loading