Можно ли сериализовать функции Haskell?
Лучший способ сделать это - получить представление о функции (если ее можно как-нибудь восстановить). Двоичная сериализация является предпочтительной по соображениям эффективности.
Я думаю, что есть способ сделать это в Clean, потому что было бы невозможно реализовать iTask, который полагается на то, что задачи (и так функции) могут быть сохранены и продолжены, когда сервер снова работает.
Это должно быть важно для распределенных вычислений на haskell.
Я не ищу синтаксический анализ кода haskell во время выполнения, как описано здесь: Сериализация функций в Haskell. Мне также нужно сериализовать, а не просто десериализовать.
5 ответов
К сожалению, это невозможно с текущей системой исполнения GHC. Сериализация функций и других произвольных данных требует некоторой низкоуровневой поддержки времени выполнения, которую разработчики ghc неохотно добавляют.
Сериализация функций требует, чтобы вы могли сериализовать все что угодно, поскольку произвольные данные (оцененные и неоцененные) могут быть частью функции (например, частичное применение).
Нет. Однако проект CloudHaskell указывает на необходимость явной поддержки сериализации замыканий в GHC. Самое близкое, что CloudHaskell имеет к явным замыканиям, - это пакет с распределенной статикой. Другая попытка - представление закрытия HdpH. Тем не менее, оба используют Template Haskell так, как Томас описывает ниже.
Ограничением является отсутствие статической поддержки в GHC, для которой в настоящее время существует неактивированный билет GHC. (Любые берут?). В списке рассылки CloudHaskell обсуждался вопрос о том, как на самом деле должна выглядеть статическая поддержка, но, насколько я знаю, пока ничего не прогрессировало.
Самым близким к разработке и внедрению является Йост Бертольд, который реализовал сериализацию функций в Eden. См. Его статью IFL 2010 "Ортогональная сериализация для Haskell". Поддержка сериализации встроена в систему исполнения Eden. (Теперь доступно в виде отдельной библиотеки: packman. Не уверен, может ли оно использоваться с GHC или требуется исправленный GHC, как в разветвлении Eden...) Для GHC потребуется нечто подобное. Это поддержка сериализации Eden, в версии разветвленной из GHC 7.4:
data Serialized a = Serialized { packetSize :: Int , packetData :: ByteArray# }
serialize :: a -> IO (Serialized a)
deserialize :: Serialized a -> IO a
Итак: можно сериализовать функции и структуры данных. E сть Binary
экземпляр для Serialized a
, что позволяет вам проверять длительные вычисления в файл! (См. Раздел 4.1).
Поддержка такого простого API-интерфейса сериализации в базовых библиотеках GHC, несомненно, станет Священным Граалем для распределенного программирования на Haskell. Скорее всего, это упростит компоновку между распределенными разновидностями Haskell ( CloudHaskell, MetaPar, HdpH, Eden и т. Д.)
Проверьте Облако Haskell. Это понятие называется Closure
который используется для отправки кода, который будет выполняться на удаленных узлах безопасным способом.
Иден, вероятно, подходит ближе всего и, вероятно, заслуживает отдельного ответа: (Де) Возможна сериализация неоцененных громад, см. https://github.com/jberthold/packman.
Однако десериализация ограничена одной и той же программой (где программа является "результатом компиляции"). Поскольку функции сериализуются как указатели кода, ранее неизвестные функции не могут быть десериализованы.
Возможное использование:
- хранение неоцененной работы на потом
- Распределение работы (но не передача нового кода)
Довольно простым и практичным, но, возможно, не таким элегантным решением было бы (желательно иметь GHC автоматически) скомпилировать каждую функцию в отдельный модуль машинно-независимого байт-кода, сериализовать этот байт-код всякий раз, когда требуется сериализация этой функции, и использовать dynamic-loader
или же plugins
пакеты, чтобы динамически загружать их, так что даже ранее неизвестные функции могут быть использованы.
Поскольку модуль отмечает все свои зависимости, они могут быть (де) сериализованы и загружены тоже. На практике, сериализация индексных номеров и добавление индексированного списка двоичных объектов байт-кода, вероятно, будет наиболее эффективным.
Я думаю, что пока вы сами компилируете модули, это уже возможно сейчас.
Как я уже сказал, это было бы не очень красиво, хотя. Не говоря уже о огромной угрозе безопасности десериализации кода из небезопасных источников для запуска в незащищенной среде.:-)
(Без проблем, если это заслуживает доверия, конечно.)
Я не собираюсь кодировать это прямо здесь, прямо сейчас.;-)