Имеет ли монада «естественную» интерпретацию в ОО, зависит от монады. В таком языке, как Java, вы можете перевести возможную монаду в язык проверки на наличие нулевых указателей, так что неудачные вычисления (т. Е. Ничего не производящие в Haskell) испускают нулевые указатели как результаты. Вы можете перевести монаду состояния на язык, созданный путем создания изменяемой переменной и методов для изменения ее состояния.
Монада - это моноид в категории эндофункторов.
Информация, которую складывает предложение, очень глубокая. И вы работаете в монаде с любым императивным языком. Монада - это «упорядоченный» предметно-ориентированный язык. Он удовлетворяет определенным интересным свойствам, которые в совокупности превращают монаду в математическую модель «императивного программирования». Haskell позволяет легко определять маленькие (или большие) императивные языки, которые можно комбинировать различными способами.
Как программист ОО, вы используете иерархию классов вашего языка для организации видов функций или процедур, которые можно вызывать в контексте, то, что вы называете объектом. Монада также является абстракцией этой идеи, поскольку различные монады могут комбинироваться произвольным образом, эффективно «импортируя» все методы субмонады в область видимости.
Архитектурно, тогда каждый использует сигнатуры типов, чтобы явно выразить, какие контексты могут использоваться для вычисления значения.
Для этой цели можно использовать монадные трансформаторы, и существует коллекция высокого качества всех «стандартных» монад:
- Списки (недетерминированные вычисления, рассматривая список как домен)
- Может быть (вычисления, которые могут дать сбой, но для которых отчетность не важна)
- Ошибка (вычисления, которые могут быть неудачными и требуют обработки исключений
- Reader (вычисления, которые могут быть представлены композициями простых функций Haskell)
- Writer (вычисления с последовательным «рендерингом» / «ведением журнала» (в строки, html и т. Д.)
- Cont (продолжение)
- IO (вычисления, которые зависят от базовой компьютерной системы)
- Состояние (вычисления, контекст которых содержит изменяемое значение)
с соответствующими монадными трансформаторами и типами классов. Классы типов допускают дополнительный подход к объединению монад, объединяя их интерфейсы, так что конкретные монады могут реализовать стандартный интерфейс для «вида» монады. Например, модуль Control.Monad.State содержит класс MonadState s m, а (State s) является экземпляром вида
instance MonadState s (State s) where
put = ...
get = ...
Длинная история состоит в том, что монада - это функтор, который присоединяет «контекст» к значению, который имеет способ ввести значение в монаду, и который имеет способ оценивать значения с учетом присоединенного к нему контекста. По крайней мере, в ограниченном порядке.
Итак:
return :: a -> m a
- это функция, которая вводит значение типа a в монадное «действие» типа m a.
(>>=) :: m a -> (a -> m b) -> m b
- это функция, которая выполняет действие монады, оценивает его результат и применяет функцию к результату. Особенность (>> =) в том, что результат находится в той же монаде. Другими словами, в m >> = f (>> =) извлекает результат из m и связывает его с f, так что результат находится в монаде. (В качестве альтернативы мы можем сказать, что (>> =) тянет f в m и применяет его к результату.) Как следствие, если у нас есть f :: a -> mb и g :: b -> mc, мы можем «последовательность» действий:
m >>= f >>= g
Или, используя «do notation»
do x <- m
y <- f x
g y
Тип (>>) может быть светящимся. Это
(>>) :: m a -> m b -> m b
Соответствует оператору (;) в процедурных языках, таких как C. Это позволяет делать обозначения, такие как:
m = do x <- someQuery
someAction x
theNextAction
andSoOn
В математической и философской логике у нас есть фреймы и модели, которые «естественно» моделируются монадизмом. Интерпретация - это функция, которая изучает область модели и вычисляет истинностное значение (или обобщения) предложения (или формулы при обобщениях). В модальной логике необходимости мы можем сказать, что суждение необходимо, если оно истинно в «каждом возможном мире» - если оно верно в отношении любой допустимой области. Это означает, что модель на языке для предложения может быть преобразована в модель, область которой состоит из набора различных моделей (одна, соответствующая каждому возможному миру). Каждая монада имеет метод с именем «join», который выравнивает слои, что подразумевает, что каждое монадное действие, результатом которого является монадное действие, может быть встроено в монаду.
join :: m (m a) -> m a
Что еще более важно, это означает, что монада закрывается при операции «укладки слоев». Вот как работают монадные преобразователи: они объединяют монады, предоставляя «похожие» методы для таких типов, как
newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
так что мы можем преобразовать действие в (MaybeT m) в действие в m, эффективно сворачивая слои. В этом случае runMaybeT :: MaybeT m a -> m (может быть a) является нашим методом, подобным соединению. (MaybeT m) является монадой, а MaybeT :: m (Может быть, a) -> MaybeT m a фактически является конструктором для нового типа действия монады в m.
Свободная монада для функтора - это монада, генерируемая суммированием f, с указанием того, что каждая последовательность конструкторов для f является элементом свободной монады (или, точнее, той же самой формы, что и дерево последовательностей). конструкторов для е). Свободные монады являются полезным методом для построения гибких монад с минимальным количеством котельной плиты. В программе на Haskell я мог бы использовать свободные монады для определения простых монад для «системного программирования высокого уровня», чтобы помочь поддерживать безопасность типов (я просто использую типы и их объявления. Реализации просты с использованием комбинаторов):
data RandomF r a = GetRandom (r -> a) deriving Functor
type Random r a = Free (RandomF r) a
type RandomT m a = Random (m a) (m a) -- model randomness in a monad by computing random monad elements.
getRandom :: Random r r
runRandomIO :: Random r a -> IO a (use some kind of IO-based backend to run)
runRandomIO' :: Random r a -> IO a (use some other kind of IO-based backend)
runRandomList :: Random r a -> [a] (some kind of list-based backend (for pseudo-randoms))
Монадизм - это основополагающая архитектура для того, что вы могли бы назвать шаблоном «интерпретатор» или «команда», абстрагируясь до его наиболее ясной формы, поскольку каждое монадическое вычисление должно быть «выполнено», по крайней мере, тривиально. (Система времени исполнения запускает для нас монаду ввода-вывода и является точкой входа в любую программу на Haskell. IO «запускает» остальные вычисления, выполняя действия IO по порядку.)
Тип для соединения также является тем, где мы получаем утверждение, что монада является моноидом в категории эндофункторов. Присоединение, как правило, более важно для теоретических целей, в силу его типа. Но понимание типа означает понимание монад. Соединяющие и монадные типы, сходные с трансформатором, по сути являются композициями эндофункторов в смысле композиции функций. Чтобы перевести это на псевдо-язык, похожий на Haskell,
Foo :: m (m a) <-> (m. M) a