Я считаю, что хотя существующие ответы в основном верны, есть более глубокая причина, по которой IO
нельзя развернуть. Концептуально , type IO a = RealWorld -> (a, RealWorld)
.IO
- это тип функции (в реальных реализациях, скрытых за оболочкой нового типа или эквивалентным механизмом).
Итак, как бы вы развернули функцию?Полегче, просто позвони!Но как вы собираетесь получить экземпляр RealWorld
?Это истинный примитив: вы не можете создать RealWorld
, он существует только один раз.
Монадический экземпляр, конечно, может просто передавать RealWorld
как состояние, вроде StateT
и вконец, единственный когда-либо созданный экземпляр - при запуске программы, затем он передается между IO
s.
Возвращаясь к реальности снова, это (снова) ложь.На самом деле вы можете получить экземпляр RealWorld
и можете вызвать действие IO a
«раньше времени».Есть функция, которая делает именно то, что вы просили.Он называется System.IO.Unsafe.unsafePerformIO :: IO a -> a
, хотя по какой-то причине он находится в небезопасном пакете.