Первый финальный подход без тегов - PullRequest
0 голосов
/ 17 июня 2020

Я пытаюсь использовать первый окончательный шаблон без тегов в Scala и немного борюсь.

У меня есть следующее определение алгебры:

trait DbSetting[F[_]] {
  def read(url: String, user: String, pw: String): F[DbParameter]
}

trait Environment[F[_]] {
  def get(v: String) : F[Option[String]]
}

и реализация интерпретатора:

final case class DbParameter(url: String, user: String, pw: String)

sealed trait DbError extends NoStackTrace
case object DbSettingError extends DbError


sealed trait DbError extends NoStackTrace
case object DbSettingError extends DbError


// Environment implementation
object Environment {

  def apply[F[_]](implicit ev: Environment[F]): ev.type = ev

  def impl[F[_]: Sync]: Environment[F] = new Environment[F] {
    override def get(v: String): F[Option[String]] =
      Sync[F].delay(sys.env.get(v))
  }
}

// DbSetting implementation
class DbSystemEnvironment[F[_] : MonadError[*, Throwable]] private(env: Environment[F])
  extends DbSetting[F] {
  override def read(url: String, user: String, pw: String): F[DbParameter] = env.get(url)

}

Я пытаюсь составить Environment в DbSystemEnvironment. Проблема здесь в том, что я не могу получить значение из env.get(url), потому что я ничего не знаю о F из DbSystemEnvironment, за исключением MonadError. Как получить значение из env.get(url)::F[Option[String]]?

Кроме того, если env.get(url) возвращает Nothing в функции read, тогда он должен вернуть MonadError.

1 Ответ

1 голос
/ 17 июня 2020

Если я правильно понимаю ваш вопрос, вы спрашиваете, как извлечь возвращаемое значение из вызова env.get(url), а затем сопоставить его с F[DbParameter].

Поскольку у вас есть MonadError для вашего F[_] вы должны легко отобразить результат, сделав что-то вроде этого:

import cats.syntax.flatMap._
import cats.syntax.applicative._
import cats.syntax.applicativeError._

override def read(url: String, user: String, pw: String): F[DbParameter] = 
  env.get(url).flatMap {
    case Some(ev) => DbParameter(ev, user, pw).pure[F]
    case None     => (new Exception("No environment parameter found!")).raiseError[F, DbParameter]
  }
...