Как написать функцию Haskell без ввода-вывода в типе sig, скрывая изменения состояния

StackOverflow https://stackoverflow.com/questions/6074222

Вопрос

Я написал на Haskell функцию, которая принимает несколько параметров, таких как Word32, String (игнорировать каррирование), и выводит IO Word32.Теперь это функция в прямом смысле: для одних и тех же входов выход всегда будет одинаковым.Побочных эффектов нет.Причина, по которой функция возвращает IO Word32 вместо Word32, заключается в том, что функция несколько раз в цикле обновляет множество 32-битных регистров сдвига с линейной обратной связью (lfsr) и других регистров, чтобы вычислить окончательный результат Word32.

Мой вопрос таков:Учитывая, что эта функция эффективно, не имеет побочных эффектов, можно ли скрыть эти обновления регистров внутри реализации функции, чтобы функция возвращала Word32, а не IO Word32?Если да, то как?

Это было полезно?

Решение

Да! Haskell может сделать это.

st monad

Если вы фактически используете мультипликационное состояние (регистры), которые полностью скрыты от наблюдателя за пределами функции, то вы находитесь в ST Monad , только для эффектов памяти. Вы вводите ST World через runST, а при выходе из функции все эффекты гарантированы не видимыми.

Именно правильная вычислительная среда для работы с локальным, воспоминанием.

<Сильное> Чисто функциональное состояние: состояние монады

Если, однако, вы на самом деле не мутируете регистры или ячейки, а скорее обновляя чисто функциональное значение много раз, доступна проще средой: Государственный монад . Это не позволяет мулюбируемому состоянию, но дает иллюзию локального состояния.

io, и unsafeperformio

Наконец, если у вас есть локальные, смежные эффекты, такие как в монаде GenaCodicetacode, но по некоторым причинам или другому вам понадобится операции IO в этом состоянии (например, через вызов FFI), вы можете имитировать ST Монад, с почти такой же безопасностью, используя ST, вместо unsafePerformIO, для введения локальной среды IO. Поскольку IO Monad не имеет хороших типов для обеспечения принудительной абстракции, вам нужно будет вручную заверить себе, что побочные эффекты не будут наблюдаемы.

Другие советы

Если вы импортировали эту функцию с помощью FFI, просто удалите IO из возвращаемого типа.В противном случае используйте unsafePerformIO :: IO a -> a от System.IO.Unsafe.Обратите внимание, что эта функция является одной из самых опасных функций в Haskell.Не используйте его, если вы не совсем уверены в последствиях.Но для вашей цели это нормально.

Да, это было бы законным использованием USAFEPERFORMEFIO. Но только в порядке, если вы действительно уверены, что нет видимых эффектов.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top