-
Notifications
You must be signed in to change notification settings - Fork 18
/
ToTry.scala
60 lines (39 loc) · 1.41 KB
/
ToTry.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package com.evolutiongaming.catshelper
import cats.Id
import cats.arrow.FunctionK
import cats.effect.IO
import scala.concurrent.TimeoutException
import scala.concurrent.duration._
import scala.util.{Failure, Success, Try}
trait ToTry[F[_]] {
def apply[A](fa: F[A]): Try[A]
}
object ToTry {
def apply[F[_]](implicit F: ToTry[F]): ToTry[F] = F
def summon[F[_]](implicit F: ToTry[F]): ToTry[F] = F
def functionK[F[_] : ToTry]: FunctionK[F, Try] = new FunctionK[F, Try] {
def apply[A](fa: F[A]): Try[A] = ToTry.summon[F].apply(fa)
}
/**
* Please think twice before using this, ideally you should not have toTry in your `pure` code base!
*
* @param timeout used only for computation after first seen async boundary, covering all computations onwards
* in case there is no async boundary found, timeout is not used
*/
def ioToTry(timeout: FiniteDuration): ToTry[IO] = new ToTry[IO] {
def apply[A](fa: IO[A]) = {
def error: Try[A] = Failure[A](new TimeoutException(timeout.toString()))
for {
a <- Try { fa.unsafeRunTimed(timeout) }
a <- a.fold(error) { a => Success(a) }
} yield a
}
}
implicit val ioToTry: ToTry[IO] = ioToTry(1.minute)
implicit val idToTry: ToTry[Id] = new ToTry[Id] {
def apply[A](fa: Id[A]) = Success(fa)
}
implicit val tryToTry: ToTry[Try] = new ToTry[Try] {
def apply[A](fa: Try[A]) = fa
}
}