Я что-то упустил из фундаментальной монады? Зачем хранить состояние и ввод отдельно?

Почему наши функции должны принимать состояние и вход, а не просто состояние, которое включает в себя вход (или вход, который включает в себя состояние?).

Я предполагаю, что вы, возможно, захотите применить разные входные данные с одним и тем же состоянием, и поэтому вы хотите хранить их отдельно, но это единственная причина?

Я чувствую, что упускаю что-то фундаментальное, но не могу этого понять.

4 ответа

Решение

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

Без монад каждая функция с состоянием выглядела бы как foo :: b -> s -> (s, a)и с помощью монад мы можем извлечь общую часть, назвать ее: newtype State s a = State (s -> (s, a))и определить return а также >>= для этого. Более того, любая простая функция bar :: a -> b можно легко превратить в состояние с помощью простого изменения результата: bar :: a -> State s b, Это было бы невозможно, если бы и вход, и состояние передавались в одном аргументе (скажем, кортеж: foo :: (s, a) -> (s, a),

Я не совсем уверен, каков ваш настоящий вопрос, но вот некоторые факты, которые могли бы ответить на него:

  1. Данные состояния изменчивы (через State монада), входные данные неизменны. В Хаскеле принято достигать максимальной безопасности на уровне типов. Если вы объединяете ввод с состоянием, вы также сделаете его изменяемым без какой-либо цели.

  2. Монады не имеют входов. Вы можете думать о стрелах. А на самом деле есть государственная стрела.

Государственная монада полезна, потому что она навязывает шаблон, который очевиден из типа.

Вместо того, чтобы каждая функция в вашем коде выглядела так:

foo state x y = ... return (state', z)

ты можешь использовать State чтобы понять, каково ваше намерение.

Терминология: если вы новичок в Haskell, вас легко запутать / одурачить такими заявлениями, как "Состояние данных изменчиво". Кто-то из императивных программ может воспринимать "изменчивость" как означающее изменение значения в существующем местоположении. Для некоторых частей Haskell (например, IORef) это действительно так. в State в случае с монадой это не так.

State поддерживает переход государства в НОВОЕ состояние - новое состояние полностью не зависит от старого. Ничего не мутировало на месте.

Иногда это называется "эффективным" программированием - вы получаете преимущества от эффектов, но без использования "настоящих" побочных эффектов - State совершенно чисто.

Другие вопросы по тегам