Монады как моноиды на практике
Я пытаюсь понять отношения между монадами и моноидами более практическими способами. Я заранее извиняюсь, если этот вопрос не имеет смысла, я все еще борюсь.
Предположим, например, что у меня есть:trait Monoid[T] {
def zero: T
def combine: (T,T) => T
}
И (из здесь):
trait Monad[+M[_]] {
def unit[A](a: A): M[A]
def bind[A, B](m: M[A])(f: A => M[B]): M[B]
}
Существует ли связь, которая может быть установлена между монадой и Моноидными чертами, например, что я могу рассматривать монаду как моноид (предполагая, что я правильно понимаю, что монада является частным случаем моноида)?1 ответ:
Вы, вероятно, увидите связь легче, если вы напишете монаду, используя
unit
иjoin
вместоunit
иbind
:trait Monoid[T] { def zero: T def combine: (T,T) => T } trait Monad[M[_]] { def unit[A]: A => M[A] def join[A]: M[M[A]] => M[A] }
Join-это Scala
Обратите внимание, что для определения монады только с помощьюflatten
, а bind-ScalaflatMap
.unit
иflatten/join
необходимо также предоставить методmap[A](m: M[A])(f: A => B): M[B]
. Это происходит из того факта, что монада на самом деле является (Эндо)функтором с двумя естественными преобразованиями, единицей и соединением. Поскольку это функтор, он имеет функциональностьmap
. Зависящий в вашем кодеmap
должен быть либо определен вместе сunit
иjoin
внутри вашего признака монады, либо унаследован от некоторого признака функтора, который будет расширен вашим признаком монады. Для полноты изложения приведу все три возможных способа определения монады:Все три могут быть выражены с помощью одного из двух других. Я пропущу код, чтобы продемонстрировать это, так как это не имеет прямого отношения к вопросу, но я могу добавить его в edit, если это необходимо.
- unit + flatMap
- unit + flatten + map
- unit + compose