@@ -10,6 +10,21 @@ import Data.Profunctor
1010-- |
1111-- | `left` and `right` lift values in a `Profunctor` to act on the `Left` and
1212-- | `Right` components of a sum, respectively.
13+ -- |
14+ -- | Looking at `Choice` through the intuition of inputs and outputs
15+ -- | yields the following type signature:
16+ -- | ```
17+ -- | left :: forall input output a. p input output -> p (Either input a) (Either output a)
18+ -- | right :: forall input output a. p input output -> p (Either a input) (Either a output)
19+ -- | ```
20+ -- | If we specialize the profunctor `p` to the `function` arrow, we get the following type
21+ -- | signatures:
22+ -- | ```
23+ -- | left :: forall input output a. (input -> output) -> (Either input a) -> (Either output a)
24+ -- | right :: forall input output a. (input -> output) -> (Either a input) -> (Either a output)
25+ -- | ```
26+ -- | When the `profunctor` is `Function` application, `left` allows you to map a function over the
27+ -- | left side of an `Either`, and `right` maps it over the right side (same as `map` would do).
1328class (Profunctor p ) <= Choice p where
1429 left :: forall a b c . p a b -> p (Either a c ) (Either b c )
1530 right :: forall a b c . p b c -> p (Either a b ) (Either a c )
@@ -24,6 +39,14 @@ infixr 2 |||
2439
2540-- | Compose a value acting on a sum from two values, each acting on one of
2641-- | the components of the sum.
42+ -- |
43+ -- | Specializing `(+++)` to function application would look like this:
44+ -- | ```
45+ -- | (+++) :: forall a b c d. (a -> b) -> (c -> d) -> (Either a c) -> (Either b d)
46+ -- | ```
47+ -- | We take two functions, `f` and `g`, and we transform them into a single function which
48+ -- | takes an `Either`and maps `f` over the left side and `g` over the right side. Just like
49+ -- | `bi-map` would do for the `bi-functor` instance of `Either`.
2750(+++) :: forall p a b c d . (Category p , Choice p ) => p a b -> p c d -> p (Either a c ) (Either b d )
2851(+++) l r = left l >>> right r
2952
@@ -32,6 +55,17 @@ infixr 2 |||
3255-- |
3356-- | This combinator is useful when assembling values from smaller components,
3457-- | because it provides a way to support two different types of input.
58+ -- |
59+ -- | Specializing `(|||)` to function application would look like this:
60+ -- | ```
61+ -- | (|||) :: forall a b c d. (a -> c) -> (b -> c) -> Either a b -> c
62+ -- | ```
63+ -- | We take two functions, `f` and `g`, which both return the same type `c` and we transform them into a
64+ -- | single function which takes an `Either` value with the parameter type of `f` on the left side and
65+ -- | the parameter type of `g` on the right side. The function then runs either `f` or `g`, depending on
66+ -- | whether the `Either` value is a `Left` or a `Right`.
67+ -- | This allows us to bundle two different computations which both have the same result type into one
68+ -- | function which will run the approriate computation based on the parameter supplied in the `Either` value.
3569(|||) :: forall p a b c . (Category p , Choice p ) => p a c -> p b c -> p (Either a b ) c
3670(|||) l r = (l +++ r) >>> join
3771 where
0 commit comments