版博士V2.0程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

175 lines
6.8 KiB

  1. /**
  2. * The `Choice` class extends `Profunctor` with combinators for working with
  3. * sum types.
  4. *
  5. * `left` and `right` lift values in a `Profunctor` to act on the `Left` and
  6. * `Right` components of a sum, respectively.
  7. *
  8. * Looking at `Choice` through the intuition of inputs and outputs
  9. * yields the following type signature:
  10. *
  11. * ```purescript
  12. * left :: forall input output a. p input output -> p (Either input a) (Either output a)
  13. * right :: forall input output a. p input output -> p (Either a input) (Either a output)
  14. * ```
  15. *
  16. * If we specialize the profunctor `p` to the `function` arrow, we get the following type
  17. * signatures:
  18. *
  19. * ```purescript
  20. * left :: forall input output a. (input -> output) -> (Either input a) -> (Either output a)
  21. * right :: forall input output a. (input -> output) -> (Either a input) -> (Either a output)
  22. * ```
  23. *
  24. * When the `profunctor` is `Function` application, `left` allows you to map a function over the
  25. * left side of an `Either`, and `right` maps it over the right side (same as `map` would do).
  26. *
  27. * Adapted from https://github.com/purescript/purescript-profunctor/blob/master/src/Data/Profunctor/Choice.purs
  28. *
  29. * @since 2.0.0
  30. */
  31. import { Either } from './Either'
  32. import { HKT2, Kind2, Kind3, URIS2, URIS3, URIS4, Kind4 } from './HKT'
  33. import { Profunctor, Profunctor2, Profunctor3, Profunctor4 } from './Profunctor'
  34. import { Category, Category2, Category3, Category4 } from './Category'
  35. /**
  36. * @category model
  37. * @since 2.0.0
  38. */
  39. export interface Choice<F> extends Profunctor<F> {
  40. readonly left: <A, B, C>(pab: HKT2<F, A, B>) => HKT2<F, Either<A, C>, Either<B, C>>
  41. readonly right: <A, B, C>(pbc: HKT2<F, B, C>) => HKT2<F, Either<A, B>, Either<A, C>>
  42. }
  43. /**
  44. * @category model
  45. * @since 2.0.0
  46. */
  47. export interface Choice2<F extends URIS2> extends Profunctor2<F> {
  48. readonly left: <A, B, C>(pab: Kind2<F, A, B>) => Kind2<F, Either<A, C>, Either<B, C>>
  49. readonly right: <A, B, C>(pbc: Kind2<F, B, C>) => Kind2<F, Either<A, B>, Either<A, C>>
  50. }
  51. /**
  52. * @category model
  53. * @since 2.0.0
  54. */
  55. export interface Choice3<F extends URIS3> extends Profunctor3<F> {
  56. readonly left: <R, A, B, C>(pab: Kind3<F, R, A, B>) => Kind3<F, R, Either<A, C>, Either<B, C>>
  57. readonly right: <R, A, B, C>(pbc: Kind3<F, R, B, C>) => Kind3<F, R, Either<A, B>, Either<A, C>>
  58. }
  59. /**
  60. * @category model
  61. * @since 2.0.0
  62. */
  63. export interface Choice4<F extends URIS4> extends Profunctor4<F> {
  64. readonly left: <S, R, A, B, C>(pab: Kind4<F, S, R, A, B>) => Kind4<F, S, R, Either<A, C>, Either<B, C>>
  65. readonly right: <S, R, A, B, C>(pbc: Kind4<F, S, R, B, C>) => Kind4<F, S, R, Either<A, B>, Either<A, C>>
  66. }
  67. /**
  68. * Compose a value acting on a sum from two values, each acting on one of
  69. * the components of the sum.
  70. *
  71. * Specializing `split` to function application would look like this:
  72. *
  73. * ```purescript
  74. * split :: forall a b c d. (a -> b) -> (c -> d) -> (Either a c) -> (Either b d)
  75. * ```
  76. *
  77. * We take two functions, `f` and `g`, and we transform them into a single function which
  78. * takes an `Either`and maps `f` over the left side and `g` over the right side. Just like
  79. * `bimap` would do for the `Bifunctor` instance of `Either`.
  80. *
  81. * @since 2.10.0
  82. */
  83. export declare function split<P extends URIS4>(
  84. P: Choice4<P>,
  85. C: Category4<P>
  86. ): <S, R, A, B, C, D>(
  87. pab: Kind4<P, S, R, A, B>,
  88. pcd: Kind4<P, S, R, C, D>
  89. ) => Kind4<P, S, R, Either<A, C>, Either<B, D>>
  90. export declare function split<P extends URIS3>(
  91. P: Choice3<P>,
  92. C: Category3<P>
  93. ): <R, A, B, C, D>(pab: Kind3<P, R, A, B>, pcd: Kind3<P, R, C, D>) => Kind3<P, R, Either<A, C>, Either<B, D>>
  94. export declare function split<P extends URIS2>(
  95. P: Choice2<P>,
  96. C: Category2<P>
  97. ): <A, B, C, D>(pab: Kind2<P, A, B>, pcd: Kind2<P, C, D>) => Kind2<P, Either<A, C>, Either<B, D>>
  98. export declare function split<P>(
  99. P: Choice<P>,
  100. C: Category<P>
  101. ): <A, B, C, D>(pab: HKT2<P, A, B>, pcd: HKT2<P, C, D>) => HKT2<P, Either<A, C>, Either<B, D>>
  102. /**
  103. * Compose a value which eliminates a sum from two values, each eliminating
  104. * one side of the sum.
  105. *
  106. * This combinator is useful when assembling values from smaller components,
  107. * because it provides a way to support two different types of input.
  108. *
  109. * Specializing `fanIn` to function application would look like this:
  110. *
  111. * ```purescript
  112. * fanIn :: forall a b c d. (a -> c) -> (b -> c) -> Either a b -> c
  113. * ```
  114. *
  115. * We take two functions, `f` and `g`, which both return the same type `c` and we transform them into a
  116. * single function which takes an `Either` value with the parameter type of `f` on the left side and
  117. * the parameter type of `g` on the right side. The function then runs either `f` or `g`, depending on
  118. * whether the `Either` value is a `Left` or a `Right`.
  119. * This allows us to bundle two different computations which both have the same result type into one
  120. * function which will run the appropriate computation based on the parameter supplied in the `Either` value.
  121. *
  122. * @since 2.10.0
  123. */
  124. export declare function fanIn<P extends URIS4>(
  125. P: Choice4<P>,
  126. C: Category4<P>
  127. ): <S, R, A, B, C>(pac: Kind4<P, S, R, A, C>, pbc: Kind4<P, S, R, B, C>) => Kind4<P, S, R, Either<A, B>, C>
  128. export declare function fanIn<P extends URIS3>(
  129. P: Choice3<P>,
  130. C: Category3<P>
  131. ): <R, A, B, C>(pac: Kind3<P, R, A, C>, pbc: Kind3<P, R, B, C>) => Kind3<P, R, Either<A, B>, C>
  132. export declare function fanIn<P extends URIS2>(
  133. P: Choice2<P>,
  134. C: Category2<P>
  135. ): <A, B, C>(pac: Kind2<P, A, C>, pbc: Kind2<P, B, C>) => Kind2<P, Either<A, B>, C>
  136. export declare function fanIn<P>(
  137. P: Choice<P>,
  138. C: Category<P>
  139. ): <A, B, C>(pac: HKT2<P, A, C>, pbc: HKT2<P, B, C>) => HKT2<P, Either<A, B>, C>
  140. /**
  141. * Use [`split`](#split) instead.
  142. *
  143. * @category zone of death
  144. * @since 2.0.0
  145. * @deprecated
  146. */
  147. export declare function splitChoice<F extends URIS3>(
  148. F: Category3<F> & Choice3<F>
  149. ): <R, A, B, C, D>(pab: Kind3<F, R, A, B>, pcd: Kind3<F, R, C, D>) => Kind3<F, R, Either<A, C>, Either<B, D>>
  150. /** @deprecated */
  151. export declare function splitChoice<F extends URIS2>(
  152. F: Category2<F> & Choice2<F>
  153. ): <A, B, C, D>(pab: Kind2<F, A, B>, pcd: Kind2<F, C, D>) => Kind2<F, Either<A, C>, Either<B, D>>
  154. /** @deprecated */
  155. export declare function splitChoice<F>(
  156. F: Category<F> & Choice<F>
  157. ): <A, B, C, D>(pab: HKT2<F, A, B>, pcd: HKT2<F, C, D>) => HKT2<F, Either<A, C>, Either<B, D>>
  158. /**
  159. * Use [`fanIn`](#fanIn) instead.
  160. *
  161. * @since 2.0.0
  162. * @deprecated
  163. */
  164. export declare function fanin<F extends URIS3>(
  165. F: Category3<F> & Choice3<F>
  166. ): <R, A, B, C>(pac: Kind3<F, R, A, C>, pbc: Kind3<F, R, B, C>) => Kind3<F, R, Either<A, B>, C>
  167. /** @deprecated */
  168. export declare function fanin<F extends URIS2>(
  169. F: Category2<F> & Choice2<F>
  170. ): <A, B, C>(pac: Kind2<F, A, C>, pbc: Kind2<F, B, C>) => Kind2<F, Either<A, B>, C>
  171. /** @deprecated */
  172. export declare function fanin<F>(
  173. F: Category<F> & Choice<F>
  174. ): <A, B, C>(pac: HKT2<F, A, C>, pbc: HKT2<F, B, C>) => HKT2<F, Either<A, B>, C>