[英]Write laws or unit test for tagless algebras
我已經寫了兩個無標簽代數,我想為其中一個寫定律。
代數如下:
@newtype case class Variable(v: String)
@newtype case class Value(v: String)
trait Environment[F[_]] {
def get(v: Variable): F[Option[Value]]
}
@newtype case class DbUrl(v: String)
@newtype case class DbUser(v: String)
@newtype case class DbPw(v: String)
final case class DbParams(url: DbUrl, user: DbUser, pw: DbPw)
trait DbConnector[F[_]] {
def read(url: DbUrl, user: DbUser, pw: DbPw): F[DbParams]
}
口譯員如下:
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: Variable): F[Option[Value]] =
Sync[F].delay(sys.env.get(v.v).map(a => Value(a)))
}
}
final case class LiveDbConnector[F[_] : MonadError[*[_], Throwable]](env: Environment[F]) extends DbConnector[F] {
override def read(url: DbUrl, user: DbUser, pw: DbPw): F[DbParams] =
(for {
a <- OptionT(env.get(Variable(url.v)))
b <- OptionT(env.get(Variable(user.v)))
c <- OptionT(env.get(Variable(pw.v)))
} yield DbParams(DbUrl(a.v), DbUser(b.v), DbPw(c.v)))
.value
.flatMap {
case Some(v) => v.pure[F]
case None => DbSettingError.raiseError[F, DbParams]
}
}
object DbConnector {
def impl[F[_] : MonadError[*[_], Throwable]](env: Environment[F])
: DbConnector[F] =
new LiveDbConnector[F](env)
在函數式編程中,有 Monoid、Monads 等規律。
我的問題是:
DbConnector
代數編寫定律您將數學定律和合理性與程序的正確性混淆了。
首先,Monad、Monoid、Fold 等不是定律。 它們是來自范疇論的數學“結構”。 這些“結構”具有它們需要遵守、健全和正確的某些特性。 例如,其中一組屬性被稱為一元定律
數學中的任何一元結構都需要遵守以下 3 條規則:
Monad、flatMap 和 pure(或數學中的 join 和 return)上的操作必須正確地遵守 function 的這些定律。 即pure(a).flatMap(f) == f(a)
, M.flatMap(pure) == M
等。
在函數式編程中,Monads 是一種從這些數學結構和規律中衍生出來的設計模式。 他們描述了一些“可組合的計算”。 在貓中 Monad 被定義為typeclass 。 這種結構符合上述規則。
我應該如何為 DbConnector 代數編寫定律
如果你想證明定律,你可能需要使用定理證明器,實際上沒有辦法在 Scala 中明確編寫或測試定律,但你總是可以編寫單元測試來確保你的 Monad 遵守這些定律,即testFlatMapLeftIdentity(...)
等。
我的代數是否需要法律或編寫單元測試就足夠了?
簡而言之,我想不出代數有明確的規律的情況,除非你的代數描述了一些數學運算集。 例如,在您的代碼中,上下文綁定MonadError[*[_], Throwable]]
需要 scope 中的Monad[F]
,假設您使用的是常見的IO, Task, Future
等,則需要遵守這些法律,貓已經做到了,所以你不必擔心這些法律。 如果您決定實現自己的效果類型或編寫新的 Monad 實現,您將需要確保遵守這些規則,但您的代碼中沒有任何內容需要您擔心它們。 為這個代數編寫好的單元測試就足夠了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.