Подтвердить что ты не робот

Что такое монад-трансформатор в отличие от монады?

Вопрос говорит все, действительно. Я знаю, что Монада (Scala) выглядит следующим образом:

trait Monad[M[_]] {
  def pure[A](a : A) : M[A]
  def bind[A, B](ma : M[A], f : A => M[B]) : M[B]
}

Как выглядит Monad Transformer? И для чего они используются?

<ч/" > ИЗМЕНИТЬ. Рассмотрим следующий сеанс REPL: если монадный трансформатор каким-то образом украшает монаду с возможностями считывателя (или наоборот)

Скажем, я просто хочу использовать replicateM из Scalaz;

scala> import scalaz._; import Scalaz._
import scalaz._
import Scalaz._

scala> some(4).replicateM[List](2)
res20: Option[List[Int]] = Some(List(4, 4))

Теперь скажем, вместо того, чтобы иметь Option[Int], мне нужно прочитать значение Int из File:

scala> val f = (_ : java.io.File) => some(1)
f: (java.io.File) => Option[Int] = <function1>

Итак, я могу рассматривать этого читателя, как если бы это была Монада?

scala> ReaderT(f).replicateM[List](2)
<console>:16: error: value replicateM is not a member of scalaz.ReaderT[Option,java.io.File,Int]
       ReaderT(f).replicateM[List](2)
                  ^

Err, no.

Извините, если все это кажется глупым, я просто пытаюсь понять, какая прекрасная доброта моя упаковка File => Option[Int] в ReaderT действительно может купить меня.

4b9b3361

Ответ 1

Монад-трансформаторы - это функции типа, которые при применении к типу монады генерируют новую монаду, которая сочетает в себе поведение обоих компонентов.

например. в диспетчере окон xmonad, вычисления выполняются внутри:

newtype X a = X (ReaderT XConf (StateT XState IO) a)

то есть a Reader, составленный с помощью State и IO монады.

  • Reader предоставляет доступ к постоянной памяти
  • State предоставляет форму состояния чтения и записи
  • IO позволяет произвольные внешние эффекты

Обратите внимание, что преобразования монады являются, таким образом, типами более высокого ранга. Они берут монадический тип вида (* -> *) и дают новый тип такого типа.

Как всегда, у Haskell wiki есть полезный контент:

Где все началось:

Ответ 2

Monad Transformers используются для объединения/расширения монад (добавьте возможности одной монады к другой). Например, ReaderT (Reader Transformer) обогащает данную монаду M возможностями Reader (преобразует данную монаду в Reader, сохраняя оригинальные функции M).

В то же время Monad Transformers являются обычными монадами, которые имеют bind, return и другие операции.

Примеры монадных трансформаторов можно найти в Scalaz - например, для Reader и State монады.

Ответ 3

Я не думаю, что Reader предназначен для чтения значений из файла. Довольно уверен, что для чтения значений конфигурации. Я рассматриваю это как альтернативу глобальным переменным, статике или динамическим/нитовым локальным переменным (называемым "специальные переменные" в Common Lisp или иногда флюидным переменным в Схеме с ним "flu-let" ). Таким образом, используйте Reader/ReaderT вместо доступа к глобальной или динамической переменной и вместо того, чтобы передавать параметры в каждый из ваших методов, которым может потребоваться доступ к некоторым параметрам конфигурации. Это может быть полезно, когда какой-то очень глубокий фрагмент кода внезапно требует доступа к новому варианту конфигурации. Вы можете передать эту функцию с помощью функции main(), скрытно получить доступ к глобальному или использовать Reader/ReaderT.