Напишите l aws или модульный тест для алгебр без тегов - PullRequest
0 голосов
/ 20 июня 2020

Я написал две алгебры без тегов, и я хотел бы написать l aws для одной из них.

Алгебры следующие:

@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)


В функциональном программировании есть l aws, такие как Monoid, Monads и др. c.

Мои вопросы:

  1. Требуется ли моим алгебрам l aws или достаточно написать модульные тесты?
  2. В чем разница между l aws и модульным тестом?
  3. Как мне написать l aws для DbConnector алгебры

1 Ответ

1 голос
/ 20 июня 2020

Вы путаете математический l aws и правильность с правильностью ваших программ.

Во-первых, Monad, Monoid, Fold et c. не л aws. Это математические «структуры», которые происходят из Теории категорий . Эти «структуры» обладают определенными свойствами, которым они должны придерживаться, чтобы быть надежными и правильными. Один набор этих свойств, например, известен как Монади c L aws

Любая структура Монади c в математике должна подчиняться этим 3 правилам:

  1. Левое удостоверение
  2. Правое удостоверение
  3. Ассоциативность

Операции с Monad, flatMap и pure (или объединение и возврат в математике) имеют чтобы быть правильным по отношению к этим l aws, чтобы нормально функционировать. ie pure(a).flatMap(f) == f(a), M.flatMap(pure) == M et c.

В функциональном программировании монады - это шаблон проектирования, полученный из этих математических структур и l aws. Они описывают некоторые «составные вычисления». В кошках Монада определяется как класс типов . Эта структура соответствует вышеупомянутым правилам.

Как мне написать l aws для алгебры DbConnector

Если вы хотите доказать l aws, вы, вероятно, должны необходимо использовать средство доказательства теорем, на самом деле нет способа явно написать или протестировать l aws в Scala, но вы всегда можете написать модульные тесты, чтобы убедиться, что ваша монада соблюдает этот закон, т.е. testFlatMapLeftIdentity(...) et c .

Нужно ли моим алгебрам l aws или достаточно написать модульные тесты?

Короче говоря, я не могу придумать случай, когда алгебра имеет явное l aws, если ваша алгебра не описывает некоторый математический набор операций. Например, в вашем коде контекстная привязка MonadError[*[_], Throwable]] требует Monad[F] в области видимости, которая должна соответствовать этим l aws, предполагая, что вы используете общий IO, Task, Future et c., Кошки сделали это так что вам не нужно беспокоиться об этих l aws. Если вы когда-нибудь решите реализовать свой собственный тип эффекта или написать новую реализацию Monad, вам нужно будет убедиться, что вы придерживаетесь этих l aws, но в вашем коде нет ничего, что заставляло бы вас беспокоиться о них. Было бы достаточно написать хорошие модульные тесты для этой алгебры.

...