@@ -23,14 +23,21 @@ package cats
23
23
package syntax
24
24
25
25
trait ApplySyntax extends TupleSemigroupalSyntax {
26
- implicit final def catsSyntaxApply [F [_], A ](fa : F [A ])(implicit F : Apply [F ]): Apply .Ops [F , A ] =
26
+ @ deprecated(" Kept for binary compatibility" , " 2.10.0" )
27
+ final def catsSyntaxApply [F [_], A ](fa : F [A ], F : Apply [F ]): Apply .Ops [F , A ] =
27
28
new Apply .Ops [F , A ] {
28
29
type TypeClassType = Apply [F ]
29
30
30
31
val self = fa
31
32
val typeClassInstance = F
32
33
}
33
34
35
+ implicit final def catsSyntaxApplyFABOps [F [_], A , B ](fab : F [A => B ]): ApplyFABOps [F , A , B ] =
36
+ new ApplyFABOps [F , A , B ](fab)
37
+
38
+ implicit final def catsSyntaxApplyFABCOps [F [_], A , B , C ](ff : F [(A , B ) => C ]): ApplyFABCOps [F , A , B , C ] =
39
+ new ApplyFABCOps [F , A , B , C ](ff)
40
+
34
41
implicit final def catsSyntaxApplyOps [F [_], A ](fa : F [A ]): ApplyOps [F , A ] =
35
42
new ApplyOps (fa)
36
43
}
@@ -40,6 +47,73 @@ private[syntax] trait ApplySyntaxBinCompat0 {
40
47
new IfApplyOps [F ](fa)
41
48
}
42
49
50
+ final class ApplyFABOps [F [_], A , B ](private val fab : F [A => B ]) extends AnyVal {
51
+
52
+ /**
53
+ * @see [[Apply.ap ]].
54
+ *
55
+ * Example:
56
+ * {{{
57
+ * scala> import cats.syntax.all._
58
+ *
59
+ * scala> val someF: Option[Int => Long] = Some(_.toLong + 1L)
60
+ * scala> val noneF: Option[Int => Long] = None
61
+ * scala> val someInt: Option[Int] = Some(3)
62
+ * scala> val noneInt: Option[Int] = None
63
+ *
64
+ * scala> someF.ap(someInt)
65
+ * res0: Option[Long] = Some(4)
66
+ *
67
+ * scala> noneF.ap(someInt)
68
+ * res1: Option[Long] = None
69
+ *
70
+ * scala> someF.ap(noneInt)
71
+ * res2: Option[Long] = None
72
+ *
73
+ * scala> noneF.ap(noneInt)
74
+ * res3: Option[Long] = None
75
+ * }}}
76
+ */
77
+ def ap (fa : F [A ])(implicit F : Apply [F ]): F [B ] = F .ap(fab)(fa)
78
+
79
+ /**
80
+ * Alias for [[ap ]].
81
+ */
82
+ def <*> (fa : F [A ])(implicit F : Apply [F ]): F [B ] = F .<*> [A , B ](fab)(fa)
83
+ }
84
+
85
+ final class ApplyFABCOps [F [_], A , B , C ](private val ff : F [(A , B ) => C ]) extends AnyVal {
86
+
87
+ /**
88
+ * @see [[Apply.ap2 ]].
89
+ *
90
+ * Example:
91
+ * {{{
92
+ * scala> import cats.syntax.all._
93
+ *
94
+ * scala> val someF: Option[(Int, Int) => Long] = Some((a, b) => (a + b).toLong)
95
+ * scala> val noneF: Option[(Int, Int) => Long] = None
96
+ * scala> val someInt1: Option[Int] = Some(3)
97
+ * scala> val someInt2: Option[Int] = Some(2)
98
+ * scala> val noneInt: Option[Int] = None
99
+ *
100
+ * scala> someF.ap2(someInt1, someInt2)
101
+ * res0: Option[Long] = Some(5)
102
+ *
103
+ * scala> noneF.ap2(someInt1, someInt2)
104
+ * res1: Option[Long] = None
105
+ *
106
+ * scala> someF.ap2(noneInt, noneInt)
107
+ * res2: Option[Long] = None
108
+ *
109
+ * scala> noneF.ap2(noneInt, noneInt)
110
+ * res3: Option[Long] = None
111
+ * }}}
112
+ *
113
+ */
114
+ def ap2 (fa : F [A ], fb : F [B ])(implicit F : Apply [F ]): F [C ] = F .ap2(ff)(fa, fb)
115
+ }
116
+
43
117
final class IfApplyOps [F [_]](private val fcond : F [Boolean ]) extends AnyVal {
44
118
45
119
@ deprecated(" Dangerous method, use ifM (a flatMap) or ifF (a map) instead" , " 2.6.2" )
@@ -61,4 +135,122 @@ final class ApplyOps[F[_], A](private val fa: F[A]) extends AnyVal {
61
135
@ deprecated(" Use <* or productL instead." , " 1.0.0-RC2" )
62
136
@ inline private [syntax] def forEffect [B ](fb : F [B ])(implicit F : Apply [F ]): F [A ] =
63
137
F .productL(fa)(fb)
138
+
139
+ /**
140
+ * @see [[Apply.productR ]].
141
+ *
142
+ * Example:
143
+ * {{{
144
+ * scala> import cats.syntax.all._
145
+ * scala> import cats.data.Validated
146
+ * scala> import Validated.{Valid, Invalid}
147
+ *
148
+ * scala> type ErrOr[A] = Validated[String, A]
149
+ *
150
+ * scala> val validInt: ErrOr[Int] = Valid(3)
151
+ * scala> val validBool: ErrOr[Boolean] = Valid(true)
152
+ * scala> val invalidInt: ErrOr[Int] = Invalid("Invalid int.")
153
+ * scala> val invalidBool: ErrOr[Boolean] = Invalid("Invalid boolean.")
154
+ *
155
+ * scala> validInt.productR(validBool)
156
+ * res0: ErrOr[Boolean] = Valid(true)
157
+ *
158
+ * scala> invalidInt.productR(validBool)
159
+ * res1: ErrOr[Boolean] = Invalid(Invalid int.)
160
+ *
161
+ * scala> validInt.productR(invalidBool)
162
+ * res2: ErrOr[Boolean] = Invalid(Invalid boolean.)
163
+ *
164
+ * scala> invalidInt.productR(invalidBool)
165
+ * res3: ErrOr[Boolean] = Invalid(Invalid int.Invalid boolean.)
166
+ * }}}
167
+ */
168
+ def productR [B ](fb : F [B ])(implicit F : Apply [F ]): F [B ] = F .productR(fa)(fb)
169
+
170
+ /**
171
+ * @see [[Apply.productL ]].
172
+ *
173
+ * Example:
174
+ * {{{
175
+ * scala> import cats.syntax.all._
176
+ * scala> import cats.data.Validated
177
+ * scala> import Validated.{Valid, Invalid}
178
+ *
179
+ * scala> type ErrOr[A] = Validated[String, A]
180
+ *
181
+ * scala> val validInt: ErrOr[Int] = Valid(3)
182
+ * scala> val validBool: ErrOr[Boolean] = Valid(true)
183
+ * scala> val invalidInt: ErrOr[Int] = Invalid("Invalid int.")
184
+ * scala> val invalidBool: ErrOr[Boolean] = Invalid("Invalid boolean.")
185
+ *
186
+ * scala> validInt.productL(validBool)
187
+ * res0: ErrOr[Int] = Valid(3)
188
+ *
189
+ * scala> invalidInt.productL(validBool)
190
+ * res1: ErrOr[Int] = Invalid(Invalid int.)
191
+ *
192
+ * scala> validInt.productL(invalidBool)
193
+ * res2: ErrOr[Int] = Invalid(Invalid boolean.)
194
+ *
195
+ * scala> invalidInt.productL(invalidBool)
196
+ * res3: ErrOr[Int] = Invalid(Invalid int.Invalid boolean.)
197
+ * }}}
198
+ */
199
+ def productL [B ](fb : F [B ])(implicit F : Apply [F ]): F [A ] = F .productL(fa)(fb)
200
+
201
+ /**
202
+ * Alias for [[productR ]].
203
+ */
204
+ def *> [B ](fb : F [B ])(implicit F : Apply [F ]): F [B ] = F .*> (fa)(fb)
205
+
206
+ /**
207
+ * Alias for [[productL ]].
208
+ */
209
+ def <* [B ](fb : F [B ])(implicit F : Apply [F ]): F [A ] = F .<* (fa)(fb)
210
+
211
+ /**
212
+ * @see [[Apply.map2 ]].
213
+ *
214
+ * Example:
215
+ * {{{
216
+ * scala> import cats.syntax.all._
217
+ *
218
+ * scala> val someInt: Option[Int] = Some(3)
219
+ * scala> val noneInt: Option[Int] = None
220
+ * scala> val someLong: Option[Long] = Some(4L)
221
+ * scala> val noneLong: Option[Long] = None
222
+ *
223
+ * scala> someInt.map2(someLong)((i, l) => i.toString + l.toString)
224
+ * res0: Option[String] = Some(34)
225
+ *
226
+ * scala> someInt.map2(noneLong)((i, l) => i.toString + l.toString)
227
+ * res0: Option[String] = None
228
+ *
229
+ * scala> noneInt.map2(noneLong)((i, l) => i.toString + l.toString)
230
+ * res0: Option[String] = None
231
+ *
232
+ * scala> noneInt.map2(someLong)((i, l) => i.toString + l.toString)
233
+ * res0: Option[String] = None
234
+ * }}}
235
+ */
236
+ def map2 [B , C ](fb : F [B ])(f : (A , B ) => C )(implicit F : Apply [F ]): F [C ] =
237
+ F .map2(fa, fb)(f)
238
+
239
+ /**
240
+ * @see [[Apply.map2Eval ]].
241
+ *
242
+ * Example:
243
+ * {{{
244
+ * scala> import cats.{Eval, Later}
245
+ * scala> import cats.syntax.all._
246
+ *
247
+ * scala> val bomb: Eval[Option[Int]] = Later(sys.error("boom"))
248
+ * scala> val x: Option[Int] = None
249
+ *
250
+ * scala> x.map2Eval(bomb)(_ + _).value
251
+ * res0: Option[Int] = None
252
+ * }}}
253
+ */
254
+ def map2Eval [B , C ](fb : Eval [F [B ]])(f : (A , B ) => C )(implicit F : Apply [F ]): Eval [F [C ]] =
255
+ F .map2Eval(fa, fb)(f)
64
256
}
0 commit comments