Я изучаю теорию категорий. Я понимаю концепцию читателя монады, это даже довольно легко реализовать:Читатель монады - как он соответствует интерфейсу Monad?
case class Reader[DEP, A](g: DEP => A) {
def apply(dep: DEP): A = g(dep)
def map[B](f: A => B): Reader[DEP, B] = Reader(dep => f(apply(dep)))
def flatMap[B](f: A => Reader[DEP, B]): Reader[DEP, B] = Reader(dep => f(apply(dep)) apply dep)
}
Однако, у меня есть проблемы, реализующие его с ограничением в какой-то общий интерфейс Монады, т.е.
trait Monad[A] {
def pure(a: A): Monad[A]
def map[B](f: A => B): Monad[B]
def flatMap[B](f: A => Monad[B]): Monad[B]
}
давайте забыли для во-вторых, есть аппликативный или функтор, и давайте просто поместим эти 3 метода здесь.
Теперь, имея этот интерфейс, у меня возникают проблемы с внедрением ReaderMonad. Метод карты довольно несгибаемый, но как насчет чистой и плоской карты? Что это значит для чтения на чистом? Чтобы реализовать flatMap, мне нужно иметь функцию от A до Reader [DEP, B], но у меня есть A => Monad [B], поэтому я не могу получить доступ.
case class Reader[DEP, A](g: DEP => A) extends Monad[A] {
def apply(dep: DEP): A = g(dep)
override def pure(a: A): Reader[DEP, A] = Reader(_ => a) // what does it even mean in case of Reader
override def map[B](f: (A) => B): Reader[DEP, B] = Reader(dep => f(apply(dep)))
override def flatMap[B](f: (A) => Monad[B]): Reader[DEP, B] = ??? // to implement it, I need f to be (A) => Reader[DEP, B], not (A) => Monad[B]
}
Возможно ли реализовать его в scala? Я пытался поиграть с собственными типами, но это тоже не сработало. Я знаю, что библиотеки, такие как скалаз или кошки, используют классные классы для реализации этих типов, но это только для образовательных целей.
Я бы посмотрел на собственную реализацию и посмотрел, как они это делают. Если вы знаете Haskell (и даже если вы этого не сделаете), возможно, стоит взглянуть на определение своего читателя Монады для подсказок. – Carcigenicate
Ну, они используют совершенно другой синтаксис (в основном, классные классы), поэтому я не уверен, что поможет – slnowak
. Основная проблема заключается в том, что ваша черта «Монады» неверна, поэтому вы не можете реально реализовать это без кастинга, как вы нашли , Обычная реализация заключается в параметризации символа «Монад» с помощью конструктора типов и его определения для «Reader [DEP, _]». – Lee