Реализация "последовательности" на монаде


Работая над другим упражнением для реализации Monad.sequence() из функционального программирования в Scala , мой ответ отличается от официального / заведомо правильного ответа:

Деф последовательности[a](ЛМА: список[Ф[А]]): Ф[список[А]]

Официальное :

def sequence[A](lma: List[F[A]]): F[List[A]] =
  lma.foldRight(unit(List[A]()))((ma, mla) => map2(ma, mla)(_ :: _))

Мое:

def sequence[A](lma: List[F[A]]): F[List[A]] = F(lma.flatten)

Пример, где F - это Option:

scala> val x: List[Option[Int]] = List( Some(1), None)
x: List[Option[Int]] = List(Some(1), None)

scala> Some(x.flatten)
res1: Some[List[Int]] = Some(List(1))
Правомерен ли здесь мой ответ (или дух его)?

Я получаю следующее исключение времени компиляции, но я конечно, если это связано с моим непониманием конструкторов типов.

Монада.scala: 15: ошибка: не найдено: значение F
Ф(лм.сплющить)

1 5

1 ответ:

Когда вы пишете Option(1), на самом деле происходит то, что вы вызываете метод apply на сопутствующем объекте Option. Это только очень косвенно связано с типом Option-в частности, нет никакого способа вообще получить сопутствующий объект Something (который является значением), если у вас есть только переменная типа, ссылающаяся на Тип Something. На самом деле нет никакой гарантии, что сопутствующий объект вообще существует, и даже если он существует, его метод apply может вернуть что-то, что полностью не является экземпляр типа Something. Тот факт, что X.apply(...) действительно возвращает X в случае классов List и Option и case, полностью зависит от соглашения.

Другая часть проблемы здесь-это призыв к List.flatten. Если вы посмотрите на "полную подпись" для flatten в docs , Вы увидите, что она имеет неявный аргумент:
def flatten[B](implicit asTraversable: (A) => GenTraversableOnce[B]): List[B]
Это означает, что вы можете использовать его только на List[A], если A можно неявно преобразовать в GenTraversableOnce некоторого вида. Это не тот случай, когда генерал для любой старой монады. Я бы посоветовал вам доказать это самому себе-попробуйте свою реализацию с некоторыми другими монадами из упражнений и посмотрите, где все ломается.