第一种最终的无标签方法

我正在尝试在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,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,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

iCMS 回答:第一种最终的无标签方法

如果我正确理解了您的问题,那么您正在询问如何从调用env.get(url)中提取返回的值,然后将其映射到F[DbParameter]

由于您的MonadErrorF[_],因此您应该可以通过以下操作很容易地映射结果:

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]
  }
本文链接:https://www.f2er.com/2114836.html

大家都在问