Трансформаторы Monad известны для всех стандартных монадов (Reader, Writer, State, Cont, List и т.д.), Но каждый из этих монадных трансформаторов работает несколько иначе. Не существует общего метода или формулы для построения монадного трансформатора с определением конструктора типа с экземпляром монады. Таким образом, не гарантируется, что тип данных монады, разработанный в соответствии с некоторыми произвольными бизнес-требованиями, будет иметь трансформатор монады. Есть ли такой явный пример?
Связанных с работой
Другой вопрос объясняет, что функторная композиция из двух монад не обязательно является монадой. См. Также этот вопрос. Эти примеры не отвечают на данный вопрос - они просто иллюстрируют проблему отсутствия общего метода построения монадного трансформатора. Эти примеры показывают, что, учитывая две монады M и N, мы иногда обнаруживаем, что M (N a) является монадой, иногда N (M a) является монадой, а иногда и не будет монадой. Но это не показывает, как построить монадный трансформатор для M или N, и не существует ли вообще.
Ответ на другой вопрос утверждает, что монада IO не может иметь трансформатор монады, потому что если бы у него был один IOT, мы могли бы применить IOT к List, а затем, подняв пустой список (lift []) в результирующую монаду, пришлось бы отменить сторону эффекты, выполненные "раньше" монадой IO. Этот аргумент основан на идее о том, что монада IO "фактически выполняет" побочные эффекты, которые, по-видимому, не могут быть отменены. Однако монада IO не является явным конструктором типов.
обсуждение
В каждом примере, где явно задан тип монады, может быть найден какой-то монадный трансформатор - иногда с определенной изобретательностью. Например, трансформатор ListT который существовал в библиотеке Haskell, относительно недавно был обнаружен некорректным тонким способом, но проблема в конечном итоге была устранена путем изменения определения ListT.
Стандартными примерами монадов без трансформаторов являются монады, такие как IO, которые на самом деле не определены явным конструктором типов. IO - непрозрачный "магический" тип, определенный библиотекой как-то на низком уровне. Кажется очевидным, что нельзя определить IO как явный конструктор типов с экземпляром монады, заданным чистыми функциями. Пример IO показывает, что монадный трансформатор может не существовать, если мы разрешаем экземпляру монады содержать скрытый низкоуровневый код с нечистыми побочными эффектами. Итак, остановим наше внимание на монадах, реализованных с использованием чистых функций.
Кажется, что не существует алгоритма, который автоматически выводит монадные трансформаторы из исходного кода монады. Мы даже знаем, что это всегда возможно?
Чтобы было более ясно, что я подразумеваю под "явным примером" монады: предположим, я утверждаю, что
type Q u v a = ((u -> (a, Maybe a)) -> v) -> u -> (a, Maybe a)
может иметь законный экземпляр Monad отношению к параметру типа a, и я создаю исходный код для реализации экземпляра Monad для Q uv когда return и join чистые функции. Знаем ли мы тогда, что Q uv имеет монадный трансформатор QT uv такой, что QT uv Id эквивалентен Q uv, и имеют место законы монадных трансформаторов? Знаем ли мы, как построить QT явно? Я не.
Чтобы решить этот вопрос, нам нужно либо
- продемонстрировать алгоритм, который найдет монадный трансформатор из произвольного заданного типа конструктора и заданной реализации экземпляра монады; например, заданный
type F a = r → Either (a, a) (a, a, Maybe a)кодаtype F a = r → Either (a, a) (a, a, Maybe a)и реализация экземпляра монады для этого, чтобы найти код для монадного трансформатора; давайте ограничимся типа конструктора, изготовленные из любой комбинации->, кортеж, иEitherдля простоты; или же - чтобы продемонстрировать контрпример: явный конструктор типа монады, заданный явным определением кода, например,
type F a = r → Either (a, a, a) (a, a, Maybe a)или что угодно, так что это законныйMonad, с экземпляромMonadзаданный чистыми функциями, но мы можем доказать, чтоFне имеет монадного трансформатора.