Неизменяемые данные от FFI и unsafePerformIO

Я делаю привязку Haskell к библиотеке загрузки изображений и хочу максимально избегать копирования. Когда изображение загружено, я получаю структуру данных из библиотеки C, содержащую данные изображения. Теперь эта структура во всех смыслах неизменяема, но чтение данных из нее в Haskell — это действие ввода-вывода. Можно ли использовать unsafePerformIO (или, возможно, unsafeDupablePerformIO для еще большей производительности), чтобы избежать копирования памяти в массив Haskell или что-то подобное? Конечно, мне нужно было бы инкапсулировать указатель структуры данных в ForeignPtr или подобное и гарантировать, что указатель не может быть доступен или изменен каким-либо другим способом.

Какова конвенция в таких случаях?


person Emil Eriksson    schedule 23.02.2014    source источник


Ответы (1)


если данные действительно неизменяемы логически, то импорт unsafePerformIO или FFI как чистой функции допустим. unsafePerformIO не является плохим по своей сути, он просто перекладывает на вас бремя доказательства того, является ли операция прозрачной с точки зрения ссылок. На самом деле иногда это сложно и неочевидно доказать, поэтому вы предоставляете возможность для большой ошибки, которую очень трудно отследить, НИКОГДА не предполагайте, что только потому, что вы не можете думать об ошибке, притворяясь, что что-то референциально прозрачный, но не означает, что все в порядке. Компилятор очень умно использует возможности для оптимизации вещей. Поэтому убедитесь, что вы действительно доказываете неизменную ссылочную прозрачность, а не просто убеждаете себя, что не можете придумать, как это может пойти не так. Но если ваши доказательства надежны, то вы не должны чувствовать себя виноватыми за их использование.

Обратите внимание, что это может иметь последствия, когда речь идет о потреблении памяти, неизменяемые значения могут оставаться в невычисленных транках, и поскольку компилятор haskell знает ваш объект только через ForeginPtr, он понятия не имеет, насколько дорого его сохранять, поэтому логическая неизменность может быть невозможна. достаточно, если ваш неизменяемый объект достаточно велик, чтобы явные аспекты времени жизни при использовании монады IO были вам полезны. система типов гарантирует правильность, эффективность — другое дело.

person John Meacham    schedule 23.02.2014