@@ -18,6 +18,9 @@ package cats
1818package mtl
1919
2020import cats .data ._
21+ import cats .syntax .applicative ._
22+ import cats .syntax .either ._
23+ import cats .syntax .functor ._
2124
2225import scala .annotation .implicitNotFound
2326import scala .util .control .NoStackTrace
@@ -235,21 +238,37 @@ object Handle extends HandleInstances with HandleCrossCompat {
235238 def rescue (h : E => F [A ])(implicit F : ApplicativeThrow [F ]): F [A ] = {
236239 val Marker = new AnyRef
237240
238- def inner [B ](fb : F [B ])(f : E => F [B ]): F [B ] =
239- ApplicativeThrow [F ].handleErrorWith(fb) {
240- case Submarine (e, Marker ) => f(e.asInstanceOf [E ])
241- case t => ApplicativeThrow [F ].raiseError(t)
242- }
241+ val fa = body(new InnerHandle (Marker ))
242+
243+ inner(fa, h, Marker )
244+ }
245+
246+ def attempt (implicit F : ApplicativeThrow [F ]): F [Either [E , A ]] = {
247+ val Marker = new AnyRef
243248
244- val fa = body(new Handle [F , E ] {
245- def applicative = Applicative [F ]
246- def raise [E2 <: E , B ](e : E2 ): F [B ] =
247- ApplicativeThrow [F ].raiseError(Submarine (e, Marker ))
248- def handleWith [B ](fb : F [B ])(f : E => F [B ]): F [B ] = inner(fb)(f)
249- })
249+ val fa = body(new InnerHandle (Marker ))
250250
251- inner(fa)(h )
251+ inner(fa.map(_.asRight), _.asLeft.pure[ F ], Marker )
252252 }
253+
254+ private def inner [B ](fb : F [B ], f : E => F [B ], Marker : AnyRef )(
255+ implicit F : ApplicativeThrow [F ]): F [B ] =
256+ ApplicativeThrow [F ].handleErrorWith(fb) {
257+ case Submarine (e, Marker ) => f(e.asInstanceOf [E ])
258+ case t => ApplicativeThrow [F ].raiseError(t)
259+ }
260+
261+ }
262+
263+ private final class InnerHandle [F [_]: ApplicativeThrow , E ](Marker : AnyRef )
264+ extends Handle [F , E ] {
265+ def applicative = Applicative [F ]
266+ def raise [E2 <: E , B ](e : E2 ): F [B ] = ApplicativeThrow [F ].raiseError(Submarine (e, Marker ))
267+ def handleWith [B ](fb : F [B ])(f : E => F [B ]): F [B ] =
268+ ApplicativeThrow [F ].handleErrorWith(fb) {
269+ case Submarine (e, Marker ) => f(e.asInstanceOf [E ])
270+ case t => ApplicativeThrow [F ].raiseError(t)
271+ }
253272 }
254273
255274 private [mtl] final case class Submarine [E ](e : E , marker : AnyRef )
0 commit comments