【问题标题】:The first final tagless approach第一个最终的无标签方法
【发布时间】:2020-10-07 04:55:40
【问题描述】:

我正在尝试在 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函数中返回Nothing,那么它应该返回MonadError

【问题讨论】:

  • 为什么要说“获取env.get(url)的值”?你想.map 它,.handle 错误还是别的什么?因为使用您为F (Sync/MonadError) 定义的代数,您可以提升值、map/flatMap 它处理、mapN 等,但不能将 F[A] 变成 A(这需要 Comonad)。
  • 切向,但我会将 ZIO (zio.dev) 视为无标签决赛的替代品。我个人觉得更容易处理。

标签: scala scala-cats tagless-final


【解决方案1】:

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

由于您的F[_]MonadError,您应该可以通过执行以下操作轻松映射结果:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-28
    • 1970-01-01
    • 2022-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-22
    相关资源
    最近更新 更多