ФУНКТОРЫ определить карту, которые имеют тип
trait Functor[F[_]] {
def map[A, B](f: A => B)(v: F[A]): F[B]
}
Монады функторы, которые поддерживают две дополнительные операции:
trait Monad[M[_]] extends Functor[M] {
def pure[A](v: A): M[A]
def join[A](m: M[M[A]]): M[A]
}
Регистрация сглаживает иерархические значения, например, если m
является List
то join
имеет типа
def joinList[A](l: List[List[A]]): List[A]
Если у вас есть монады m
и вы map
над ним, что произойдет, если b
тот же монадический типа? Например:
def replicate[A](i: Int, value: A): List[A] = ???
val f = new Functor[List] {
def map[A, B](f: A => B)(v: List[A]) = v.map(f)
}
затем
f.map(x => replicate(x, x))(List(1,2,3)) == List(List(1), List(2,2), List(3,3,3))
Это имеет тип List[List[Int]]
а вход является List[Int]
. Для цепочки операций довольно часто требуется, чтобы каждый шаг возвращал один и тот же тип ввода. Поскольку List
также могут быть сделаны в монады, вы можете легко создать такой список, используя join
:
listMonad.join(List(List(1), List(2,2), List(3,3,3))) == List(1,2,2,3,3,3)
Теперь вы можете написать функцию, чтобы объединить эти две операции в одну:
trait Monad[M] {
def flatMap[A, B](f: A => M[B])(m: M[A]): M[B] = join(map(f)(m))
}
то вы можете просто сделать:
listMonad.flatMap(List(1,2,3), x => replicate(x, x)) == List(1,2,2,3,3,3)
Именно то, что делает flatMap
зависит от типа монады конструктора M
(List
в этом примере), поскольку он зависит от map
и join
.
Это не вводите StackOverflow в Вопросительный – UserNotFoundException
flatmap = карта + расплющить – 757071
Какой вопрос тогда? –