1 ```import Foundation ``` 2 3 ```/// A Comonad is the dual of a `Monad`. It provides capabilities to compose functions that extract values from their context. ``` 4 ```/// ``` 5 ```/// Implementations of this instance must obey the following laws: ``` 6 ```/// ``` 7 ```/// extract(duplicate(fa)) == fa ``` 8 ```/// map(fa, f) == coflatMap(fa, { a in f(extract(a)) } ``` 9 ```/// coflatMap(fa, extract) == fa ``` 10 ```/// extract(coflatMap(fa, f)) == f(fa) ``` 11 ```/// ``` 12 ```public protocol Comonad: Functor { ``` 13 ``` /// Applies a value in the context implementing this instance to a function that takes a value in a context, and returns a normal value. ``` 14 ``` /// ``` 15 ``` /// This function is the dual of `Monad.flatMap`. ``` 16 ``` /// ``` 17 ``` /// - Parameters: ``` 18 ``` /// - fa: Value in the context implementing this instance. ``` 19 ``` /// - f: Extracting function. ``` 20 ``` /// - Returns: The result of extracting and transforming the value, in the context implementing this instance. ``` 21 ``` static func coflatMap(_ fa: Kind, _ f: @escaping (Kind) -> B) -> Kind ``` 22 23 ``` /// Extracts the value contained in the context implementing this instance. ``` 24 ``` /// ``` 25 ``` /// This function is the dual of `Monad.pure` (via `Applicative`). ``` 26 ``` /// ``` 27 ``` /// - Parameter fa: A value in the context implementing this instance. ``` 28 ``` /// - Returns: A normal value. ``` 29 ``` static func extract(_ fa: Kind) -> A ``` 30 ```} ``` 31 32 ```// MARK: Related functions ``` 33 34 ```public extension Comonad { ``` 35 ``` /// Wraps a value in another layer of the context implementing this instance. ``` 36 ``` /// ``` 37 ``` /// - Parameter fa: A value in the context implementing this instance. ``` 38 ``` /// - Returns: Value wrapped in another context layer. ``` 39 1 ``` static func duplicate(_ fa: Kind) -> Kind> { ``` 40 1 ``` return coflatMap(fa, id) ``` 41 ``` } ``` 42 ```} ``` 43 44 ```// MARK: Syntax for Comonad ``` 45 46 ```public extension Kind where F: Comonad { ``` 47 ``` /// Applies this value to a function that takes a value in this context, and returns a normal value. ``` 48 ``` /// ``` 49 ``` /// This function is the dual of `Monad.flatMap`. ``` 50 ``` /// ``` 51 ``` /// This is a convenience function to call `Comonad.coflatMap` as an instance method. ``` 52 ``` /// ``` 53 ``` /// - Parameters: ``` 54 ``` /// - f: Extracting function. ``` 55 ``` /// - Returns: The result of extracting and transforming the value, in the context implementing this instance. ``` 56 1 ``` func coflatMap(_ f: @escaping (Kind) -> B) -> Kind { ``` 57 1 ``` return F.coflatMap(self, f) ``` 58 ``` } ``` 59 60 ``` /// Extracts the value contained in this context. ``` 61 ``` /// ``` 62 ``` /// This function is the dual of `Monad.pure` (via `Applicative`). ``` 63 ``` /// ``` 64 ``` /// This is a convenience function to call `Comonad.extract` as an instance method. ``` 65 ``` /// ``` 66 ``` /// - Returns: A normal value. ``` 67 1 ``` func extract() -> A { ``` 68 1 ``` return F.extract(self) ``` 69 ``` } ``` 70 71 ``` /// Wraps this in another layer of this context. ``` 72 ``` /// ``` 73 ``` /// - Returns: This value wrapped in another context layer. ``` 74 0 ``` func duplicate() -> Kind> { ``` 75 0 ``` return F.duplicate(self) ``` 76 ``` } ``` 77 ```} ```

Read our documentation on viewing source code .