Вот Monad
экземпляр для ListT
(скопировано с montrivo )
case class ListT[M[_], A](value: M[List[A]])
implicit def listTMonad[M[_]: Monad] = new Monad[ListT[M, *]] {
override def flatMap[A, B](fa: ListT[M, A])(f: A => ListT[M, B]): ListT[M, B] =
ListT(
Monad[M].flatMap[List[A], List[B]](fa.value)(
list => Traverse[List].flatTraverse[M, A, B](list)(a => f(a).value)
)
)
override def pure[A](a: A): ListT[M, A] = ListT(Monad[M].pure(List(a)))
override def tailRecM[A, B](a: A)(f: A => ListT[M, Either[A, B]]): ListT[M, B] = ???
}
Это не удовлетворяет ассоциативность закон монады
val a: Int => ListT[List, Int] = {
case 0 => ListT(List(List(0, 1)))
case 1 => ListT(List(List(0), List(1)))
}
assert(a(0).flatMap(a).flatMap(a) != a(0).flatMap(x ⇒ a(x).flatMap(a)), "Associativity law is not satisfied")
, потому что, хотя мы получаем одинаковые значения, они находятся в разном порядке
ListT(List(List(0, 1, 0, 0, 1), List(0, 1, 1, 0, 1), List(0, 1, 0, 0), List(0, 1, 0, 1), List(0, 1, 1, 0), List(0, 1, 1, 1)))
ListT(List(List(0, 1, 0, 0, 1), List(0, 1, 0, 0), List(0, 1, 0, 1), List(0, 1, 1, 0, 1), List(0, 1, 1, 0), List(0, 1, 1, 1)))
Однако, похоже, он работает правильно для-понимания (в моем личном проекте ). Вообще, безопасно ли использовать «монады», которые нарушают закон ассоциативности для понимания? Не могли бы вы привести контрпример, показывающий неверный результат?