softshipper
softshipper

Reputation: 34071

How to wrap effectful F instead of the concrete type constructor?

I have the following function definition:

  private val checkSapHealth: IO[ServerHealth] =
    BlazeClientBuilder[IO](global).resource.use { client =>
      discovery
        .senderAddr
        .flatMap { addr =>
          client
            .get(addr.url |+| addr.health) { res =>
              res.status match {
                case Ok =>
                  IO(ServerOnline)
                case _ =>
                  IO(ServerOffline)
              }
            }
            .timeout(2.second)
            .recover {
              case _: Throwable => ServerOffline
            }

        }
    }

I would like to replace the concrete type IO through F[_] to make it more abstract. The problem here is the line:

IO(ServerOnline)

The question is how to make it to

F(ServerOnline)

Upvotes: 1

Views: 230

Answers (2)

Sagi
Sagi

Reputation: 9284

use ConcurrentEffect and add an implicit Applicative of F, thus giving you the option to lift values into the F context

private def checkSapHealth[F[_] : ConcurrentEffect](implicit A: Applicative[F]): F[ServerHealth] =
  BlazeClientBuilder[F](global).resource.use { client =>
    discovery
      .senderAddr
      .flatMap { addr =>
        client
          .get(addr.url |+| addr.health) { res =>
            res.status match {
              case Ok =>
                A.pure(ServerOnline)
              case _ =>
                A.pure(ServerOffline)
            }
          }
          .timeout(2.second)
          .recover {
            case _: Throwable => ServerOffline
          }
      }
  }

Upvotes: 1

Dmytro Mitin
Dmytro Mitin

Reputation: 51658

Try to use cats.effect.Sync

https://typelevel.org/cats-effect/typeclasses/sync.html

So basically using Sync[IO].delay is equivalent to using IO.apply.

private def checkSapHealth[F[_]: Sync]: F[ServerHealth] = ...

Upvotes: 2

Related Questions