Требуется ли доступ к внутренней структуре монады для преобразователя монады?

Нужно ли иметь доступ к внутренней структуре монады, чтобы написать преобразователь монады?

Например: Я хотел бы иметь GetT - преобразователь для монады Get из Data.Binary.Get, но этот модуль не раскрывает внутренности монады Get. Означает ли это, что единственный способ для меня — добавить GetT непосредственно в модуль Data.Binary.Get?


person Victor Denisov    schedule 03.08.2012    source источник
comment
Я думаю, что обычно все наоборот. Реальную реализацию монады определяет преобразователь монады, а затем вы применяете его к монаде Identity, чтобы получить базовый экземпляр этой монады (например, вы применяете StateT к Identity, чтобы получить State). Осторожно, я не уверен в этом :)   -  person Riccardo T.    schedule 03.08.2012


Ответы (1)


В общем, да. Посмотрите в этом примере, как внутренняя монада (здесь монада списка) может «отменить» эффект «более раннего» действия внешней монады:

> execWriterT (tell "Hi" >> tell "Ho" >> lift [()])
["HiHo"]
> execWriterT (tell "Hi" >> tell "Ho" >> lift [])
[]

Теперь предположим, что вы можете превратить каждую монаду в монадный преобразователь. Тогда вы сможете сконструировать IOT монадный преобразователь, и это может запустить ракету, но затем отменить ее:

> execIOT (launchMissile >> lift [])

Следовательно, невозможно превратить произвольную монаду, не глядя на определение, в монадный преобразователь.

person Joachim Breitner    schedule 03.08.2012
comment
Я правильно понимаю, что вы приводите этот случай как пример, когда вам не нужна информация о внутренней структуре? Но на самом деле вы используете тот факт, что внутренняя монада — это список. - person Victor Denisov; 03.08.2012
comment
Нет; речь идет о внутренней структуре монады, которую вы хотите превратить в преобразователь, в данном случае IO (а в вашем случае Get). Вам никогда не понадобится информация о внутренней структуре монады, которую вы хотите обернуть. Это приводит к вопросу, почему вам нужен преобразователь GetT в первую очередь, то есть чего вы хотите достичь? - person Joachim Breitner; 03.08.2012
comment
У меня есть код, в котором я общаюсь через сокет с помощью Handler. - person Victor Denisov; 03.08.2012
comment
У меня есть структура данных, которую я хотел бы проанализировать из обработчика. Мне также нужно общаться с помощью консоли и что-то писать в обработчик (выполнять некоторые операции ввода-вывода). Я хотел бы сделать hGetContents и позволить монаде Get отслеживать, сколько данных было проанализировано. - person Victor Denisov; 03.08.2012
comment
Если вопрос «требуется ли доступ к внутренней структуре для написания преобразователя монады», разве ответ не будет «да»? - person John L; 03.08.2012
comment
@VictorDenisov - учитывая эти требования, вы можете захотеть изучить один из различных вариантов итерации (итерация, канал, трубы, множество вариантов). Эта проблема в значительной степени находится непосредственно в их пространстве дизайна. - person John L; 03.08.2012
comment
Почему execIOT (launchMissile >> lift []) должен был сначала запустить ракету, а потом отменить ее? Я ожидаю, что выражение launchMissile >> lift [] является просто значением IOT [], которое не запускает никаких ракет, поэтому execIOT не нужно ничего делать при его выполнении. - person winitzki; 05.03.2019