26

最好的方法是获取函数的表示(如果它可以以某种方式恢复)。出于效率原因,首选二进制序列化。

我认为在 Clean 中有一种方法可以做到这一点,因为不可能实现 iTask,它依赖于在服务器再次运行时可以保存并继续执行任务(以及函数)。

这对于分布式haskell计算来说一定很重要。

我不是在寻找在运行时解析haskell代码,如下所述:Serialization of functions in Haskell。我还需要序列化而不仅仅是反序列化。

4

5 回答 5

28

不幸的是,当前的 ghc 运行时系统是不可能的。函数和其他任意数据的序列化需要一些 ghc 实现者不愿添加的低级运行时支持。

序列化函数要求您可以序列化任何东西,因为任意数据(已评估和未评估)可以是函数的一部分(例如,部分应用程序)。

于 2013-07-22T11:46:35.137 回答
22

不会。但是,CloudHaskell 项目正在推动 GHC 中对显式闭包序列化支持的需求。CloudHaskell 最接近显式闭包的是分布式静态包。另一种尝试是HdpH 闭包表示。但是,两者都按照 Thomas在下面描述的方式使用 Template Haskell 。

限制是 GHC 缺乏静态支持,目前有一个未执行的GHC 票证。(有接受者吗?)。CloudHaskell 邮件列表上已经讨论过静态支持应该是什么样子,但据我所知,还没有任何进展。

最接近设计和实现的人是 Jost Berthold,他在 Eden 中实现了函数序列化。请参阅他的 IFL 2010 论文“Haskell 的正交序列化”。序列化支持已融入 Eden 运行时系统。(现在可作为单独的库:packman。不确定它是否可以与 GHC 一起使用或需要像 Eden fork 中的修补 GHC ......)GHC 需要类似的东西。这是从 GHC 7.4 派生的版本中的序列化支持 Eden:

data Serialized a = Serialized { packetSize :: Int , packetData :: ByteArray# }
serialize   :: a -> IO (Serialized a)
deserialize :: Serialized a -> IO a

所以:可以序列化函数数据结构。有一个Binary实例Serialized a,允许您检查点长时间运行的计算以归档!(见第 4.1 节)。

在 GHC 基础库中支持这样一个简单的序列化 API 肯定是分布式 Haskell 编程的圣杯。它可能会简化分布式 Haskell 风格(CloudHaskellMetaParHdpHEden等...)之间的可组合性

于 2013-07-22T15:45:37.467 回答
20

查看Cloud Haskell。它有一个名为的概念Closure,用于以类型安全的方式发送要在远程节点上执行的代码。

于 2013-07-22T11:38:53.180 回答
2

伊甸园可能是最接近的,可能值得单独回答:(反)未评估的 thunk 的序列化是可能的,请参阅https://github.com/jberthold/packman

然而,反序列化仅限于同一个程序(其中程序是“编译结果”)。由于函数被序列化为代码指针,因此无法反序列化以前未知的函数。

可能的用法:

  • 存储未评估的工作以备后用
  • 分发工作(但不共享新代码)
于 2015-10-06T12:25:29.163 回答
0

一个非常简单实用但可能没有那么优雅的解决方案是(最好让 GHC 自动)将每个函数编译成一个独立于机器的字节码模块,在需要序列化该函数时序列化该字节码,并使用dynamic-loaderorplugins包, 动态加载它们,因此甚至可以使用以前未知的功能。

由于模块记录了它的所有依赖项,因此也可以对这些依赖项进行(反)序列化和加载。在实践中,序列化索引号并附加字节码 blob 的索引列表可能是最有效的。

我认为只要你自己编译模块,这已经是可能的了。

正如我所说,它不会很漂亮。更不用说从不安全的来源反序列化代码以在不安全的环境中运行通常会带来巨大的安全风险。:-)
(当然,如果它值得信赖,那没问题。)

不过,我现在不打算在这里编写代码。;-)

于 2016-12-07T04:39:31.873 回答