簡體   English   中英

第一個最終的無標簽方法

[英]The first final tagless approach

我正在嘗試在 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)中獲取值,因為我對DbSystemEnvironment中的F一無所知,除了它是MonadError 如何從env.get(url)::F[Option[String]]中獲取值?

此外,如果env.get(url)read function 中返回Nothing ,那么它應該返回MonadError

如果我正確理解您的問題,您是在詢問如何從調用env.get(url)中提取返回值,然后將 map 提取到F[DbParameter]

由於您的F[_]MonadError ,您應該能夠通過執行以下操作很容易地獲得 map 結果:

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]
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM