Каждый метод, возвращающий this, является монадой? - PullRequest
5 голосов
/ 19 августа 2010

Является ли каждый метод в классе, который возвращает this монадой?

Ответы [ 4 ]

7 голосов
/ 19 августа 2010

Я собираюсь сказать очень осторожно "возможно". Многое из этого зависит от ваших определений.

Стоит отметить, что я беру определение монады из теории теории категорий , а не из функционального программирования .

Если вы думаете о методе A класса C, который отображает экземпляр C на другой экземпляр C (т. Е. Он возвращает this), тогда может показаться, что C.A() является функтором из категории, состоящей из C экземпляров к себе. Поэтому, по крайней мере, это эндофунктор. Может показаться, что эта конструкция подчиняется основным свойствам идентичности и ассоциативности, которые мы ожидаем, но для точной проверки потребуется дополнительная проверка.

В любом случае, я бы не стал рисковать своей жизнью, и я не уверен, что это очень полезный способ думать о таких конструкциях, но, по крайней мере, при первом осмотре это кажется разумным предположением.

4 голосов
/ 15 ноября 2010

Вероятно, нет, по крайней мере, ни одним из обычных способов.

Монады в программировании обычно определяются по категории типов с функциями в виде стрелок.В этом случае метод, возвращающий this, является стрелкой от класса к себе - это эндо морфизм с обычным моноидом композиции функций, но не является функтором .

Обратите внимание, что функторы с типами функций, безусловно, возможны, но функтор F(A) => (A -> A) на самом деле не работает, потому что тип появляется как в ковариантном, так и в контравариантном положении, то есть, учитывая функцию A -> B, вы можетеотправить A -> A на A -> B, или вы можете отправить B -> B на A -> B, но вы не можете получить B -> B от A -> A или наоборот.


Однако,есть один способ рассматривать экземпляры как имеющие монадическую структуру.Учтите, что методы экземпляра фактически имеют this в качестве неявного аргумента.Таким образом, для некоторого класса C его методы являются функциями от C до любого другого типа.Это примерно соответствует ковариантной функции функтора выше.Обратите внимание, что я не описываю здесь какой-либо конкретный класс , а весь концепт классов и экземпляров!Итак, для этого отображения из C в методы экземпляра C:

  • Если у нас есть метод экземпляра, возвращающий некоторый тип A, и функцию с типом A -> B, мы можем тривиально определитьметод, возвращающий что-то типа B: это остальная часть определения функтора, также называемая 'fmap` в Haskell.

  • Если у нас есть какое-то значение типа A, мы можемдобавьте тривиальный метод экземпляра, который просто возвращает это значение: это «единичная» операция монады, иначе говоря, return в Haskell.

  • Если у нас есть метод экземпляра, возвращающий значение типа A, и другой метод экземпляра, принимающий аргумент типа A и возвращающий значение типа B, мыМожно определить метод, который просто возвращает значение типа B, комбинируя их.Это монадное связывание, также называемое (>>=) в Haskell.

Haskell вызывает монаду «функций, которые все принимают первый аргумент некоторого фиксированного типа» - Монаду Читателя и do нотация для него позволяет вам писать код, в котором этот первый аргумент неявно доступен - скорее как способ, которым this неявно доступен внутри методов экземпляра.

Различие здесь в том, что с экземплярами класса монадическая структураэто ... что-то вроде уровня синтаксиса , а не то, что вы можете использовать непосредственно в программе, по крайней мере, в большинстве языков.

4 голосов
/ 19 августа 2010

У меня ограниченное понимание монад. Я не могу сказать, соответствует ли это формальному определению монады (я так не думаю, но точно не знаю), но один return this; не позволяет ни одной из классных вещей, которые допускают монады (флюид интерфейсы хороши, но не монады imho и нигде не так полезны, как даже простые монады, такие как опция типа монады).

Этот фрагмент из Википедии, похоже, говорит "нет":

Формально монада создается путем определения двух операций (связывание и возврат) и конструктора типа M [... дальнейшие ограничения здесь не нужны]

Редактировать: Более того, монада - это тип, а не операция (например, метод) - вопрос должен звучать так: «Является ли класс монадой, если все его методы возвращают this

1 голос
/ 20 августа 2010

На мой взгляд, нет.

У меня есть как минимум две проблемы.

  1. Монада часто является связующим звеном между двумя функциями. В этом случае methodA возвращает тип, для которого вызывается следующий methodB (и, конечно, methodA и methodB оба принадлежат того же типа).
  2. Монада должна разрешать преобразования типов. Поэтому, если functionA возвращает TypeX и functionB ожидает TypeY , монаде необходимо предоставить операцию связывания, которая может преобразовать монаду (TypeX) в монаду (TypeY) . Затем монада принимает возвращаемое значение первой функции, оборачивает его в монаду (TypeX) , преобразует в монаду (TypeY) , из которой TypeY извлекается и подается в functionB .

Метод, который возвращает это, на самом деле является реализацией Fluent Interface. И хотя многие утверждают, что это тоже монада, я бы сказал, что, хотя он помогает решать проблемы, аналогичные тем, которые монады могут решить в противном случае, и хотя решение может показаться похожим на то, как монадическое решение может работать (вместо " ", метод связывания монады должен вызываться без какого-либо явного блока do), это не монада. Другими словами, он может идти как монада и говорить как монада, но это не монада.

Небольшая коррекция к точке 2 : Монада должна предоставить механизмы для а) преобразования TypeX в монаду (TypeX), преобразования из монады (TypeX) в монаду (TypeY) и приведения из монады (TypeY) ) для типа Y

...