Что такое монада-трансформер в отличие от монады?
вопрос говорит все это, на самом деле. Я знаю (Scala)монады выглядит так:
trait Monad[M[_]] {
def pure[A](a : A) : M[A]
def bind[A, B](ma : M[A], f : A => M[B]) : M[B]
}
что делает Монада трансформатор выглядеть? И для чего они используются?
редактировать. рассмотрим следующий сеанс 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, нет.
извинения, если все это кажется глупым, я просто пытаюсь понять, какая прекрасная доброта моя упаковка File => Option[Int]
на ReaderT
на самом деле может купить меня.
3 ответов
трансформаторы монады-это функции типа, которые при применении к типу монады генерируют новую монаду, которая сочетает в себе поведение обоих компонентов.
Е. Г. в xmonad
диспетчер окон, вычисления выполняются внутри:
newtype X a = X (ReaderT XConf (StateT XState IO) a)
то есть a Reader
состоит с State
и IO
монады.
-
Reader
дает доступ к памяти только для чтения -
State
обеспечивает форму состояния чтения-записи -
IO
позволяет произвольные внешние эффекты
обратите внимание, что преобразования монады, таким образом, являются типами более высокого ранга. Они принимают монадический тип рода (* -> *
), и дать новый тип такого рода.
как всегда, Haskell wiki имеет полезный контент:
где все это начал:
трансформаторы монады использованы для совмещать / удлиняя монады (добавьте возможности одной монады к другим). Е. Г., ReaderT
(читатель трансформатор) обогащает данную монаду M
С Reader
возможности (превращает данную монаду в читателя, сохраняя оригинальные функции M
).
в то же время трансформаторы монады являются нормальными монадами, которые имеют bind
, return
и другие операции.
вы можете найти примеры трансформаторов монады в Scalaz - например,читатель и государство монады.
Я не думаю, что Reader предназначен для чтения значений из файла. Уверен, что это для чтения значений конфигурации. Я думаю об этом как об альтернативе глобальным переменным, статике или динамическим/локальным переменным (называемым "специальными переменными" в Common Lisp или иногда переменными fluide в схеме с "fluid-let"). Таким образом, используйте Reader / ReaderT вместо доступа к глобальной или динамической переменной и вместо передачи параметров в каждый из ваших методов, которые могут потребовать доступа к некоторой конфигурации выбор. Это может быть полезно, когда какой-то очень глубокий фрагмент кода внезапно требует доступа к новой опции конфигурации. Вы можете передать опцию из функции main (), незаметно получить доступ к глобальному или использовать Reader/ReaderT.