Почему IO — это монада, а не комонада?

Результатом является эффективное вычисление. Таким образом, имеет смысл инкапсулировать его в монаду. Но ввод — это контекстно-зависимое вычисление. Таким образом, было бы более разумно инкапсулировать его в комонаду.

Однако в Haskell ввод и вывод инкапсулированы в монаду IO. Почему?


person Bob    schedule 05.08.2014    source источник


Ответы (2)


Комонада имеет метод extract :: w a -> a, который не может быть (разумно) реализован для IO.

Ввод на самом деле не зависит от контекста в смысле комонады. "Контекстная чувствительность" для комонады означает, что она чувствительна к более широкому контексту в структуре данных. Например, застежка-молния списка похожа на список с некоторой дополнительной информацией о позиции о том, «где мы находимся» в списке в любой момент времени. На самом деле в структуре данных IO нет никакой фактической структуры, поэтому нет контекста, к которому она могла бы быть чувствительна.

Структура Monad позволяет нам получить доступ к входным данным внутри типа IO с помощью операции >>=, так что все работает нормально.

Кроме того, обратите внимание, что термины "эффективный" и "контекстно-зависимый" являются своего рода неформальными и, как следствие, могут полностью не иметь смысла для всех примеров монад и комонад: действительно ли функциональная монада " эффектный"? Действительно ли комонада (,) e «зависима от контекста»?

Кстати, лучший способ развить интуицию о том, как работают монады и комонады, — это получить опыт их использования (это касается и многих других вещей). К сожалению, нет хорошего способа суммировать их с помощью короткой фразы вроде "эффективный" или "контекстно-зависимый" таким образом, чтобы дать вам представление о том, как они на самом деле работают. Эти фразы могут помочь некоторым, но важно помнить об их ограничениях.

Кроме того, лучший способ понять класс типов — это понять его экземпляры (попробуйте просмотреть все предоставленные экземпляры и разобраться в них). Как только вы это сделаете, вы сможете посмотреть, как класс типов соединяется со всеми ними. Это даст вам хорошее представление о том, что «означает» класс типов. Я также должен отметить, что это хорошая идея держать в уме (по крайней мере) любые законы, которые могут быть предусмотрены для класса типов, при просмотре его экземпляров.

person David Young    schedule 05.08.2014

Подпись comonad extract :: w a -> a означает, что мы можем вычислить a с помощью чистого вычисления, без каких-либо побочных эффектов.

С другой стороны, мы используем IO, когда хотим создать какую-то ценность, используя побочные эффекты. Даже вещи, которые кажутся входными, имеют побочные эффекты. Например: получение данных по сети, чтение байтов из файла и продвижение позиции потока, чтение данных из базы данных может иметь побочные эффекты, такие как открытие сетевого соединения, регистрация доступа, активация некоторых триггеров и т. д. Таким образом, comonad не является правильная абстракция для IO.

person Petr    schedule 06.08.2014
comment
Хорошо, функции отображают ввод в вывод, но некоторые функции игнорируют их ввод, например f x = 1. Многие функторы/монады также игнорируют свой контейнер/контекст. - person aoeu256; 06.08.2019