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