Cli*_*ton 6 serialization haskell cloud-haskell
我一直在玩Cloud Haskell.我在hackage文档中注意到有一种应用程序界面.但特别是我正在尝试closurePure
使用以下签名查找或编写函数:
closurePure :: (Typeable a, Binary a) => a -> Closure a
Run Code Online (Sandbox Code Playgroud)
这基本上是纯粹的限制版本.
虽然Closure
数据类型本身是抽象的,但以下closure
提供了:
closure :: Static (ByteString -> a) -> ByteString -> Closure a
Run Code Online (Sandbox Code Playgroud)
所以我可以做到这一点:
closurePure :: (Typeable a, Binary a) => a -> Closure a
closurePure x = closure ??? (encode x)
Run Code Online (Sandbox Code Playgroud)
问题是在什么地方放置???
.
我的第一次尝试如下:
myDecode :: (Typeable a, Binary a) => Static (ByteString -> a)
myDecode = staticPtr (static decode)
Run Code Online (Sandbox Code Playgroud)
但是在阅读关于静态指针的GHC文档时,该show
示例向我建议您不能有约束,因为受约束的函数没有Typeable
实例.所以我尝试了使用的建议Dict
:
myDecode :: Typeable a => Static (Dict (Binary a) -> ByteString -> a)
myDecode = staticPtr (static (\Dict -> decode))
Run Code Online (Sandbox Code Playgroud)
但现在我的错误类型不符合上述closure
功能.
无论如何要写closurePure
或类似的东西(或者我在Cloud Haskell文档中错过了它)?将binary
普通类型提升为Closure
s对于使用给定的应用界面似乎是必不可少的,但我无法弄清楚如何去做.
请注意,我可以这样做:
class StaticDecode a where
staticPtrDecode :: StaticPtr (ByteString -> a)
instance StaticDecode Int where
staticPtrDecode = static Data.Binary.decode
instance StaticDecode Float where
staticPtrDecode = static Data.Binary.decode
instance StaticDecode Integer where
staticPtrDecode = static Data.Binary.decode
-- More instances etc...
myPure :: forall a. (Typeable a, StaticDecode a, Binary a) => a -> Closure a
myPure x = closure (staticPtr staticPtrDecode) (encode x)
Run Code Online (Sandbox Code Playgroud)
哪个效果很好,但基本上要求我为每个Binary
实例重复一个实例.看起来很乱,我更喜欢另一种方式.
你是对的,它Closure
有一个类似应用程序的结构,这一事实在分布式闭包的接口和实现中都变得更加明确。它不太适用,因为在这种pure
情况下,我们确实有额外的约束,即参数必须以某种方式可序列化。
事实上,我们有一个更强的约束。不仅参数必须是可序列化的,而且约束本身也必须是可序列化的。就像很难直接序列化函数一样,您可以想象很难序列化约束。但就像函数一样,技巧是序列化一个指向约束本身的静态指针(如果存在这样的静态指针)。我们怎么知道这样的指针存在呢?我们可以引入一个带有单个方法的类型类,该方法在给定约束的情况下为我们提供指针的名称:
class GimmeStaticPtr c where
gimmeStaticPtr :: StaticPtr (Dict c)
Run Code Online (Sandbox Code Playgroud)
这里有一个小小的技术技巧。类型索引的种类StaticPtr
是 kind *
,而约束则具有 kind Constraint
。因此,我们重用约束库中的一个技巧,即将约束包装到数据类型中(Dict
上面),就像所有数据类型一样*
。具有关联GimmeStaticPtr
实例的约束称为静态约束。
一般来说,有时组合静态约束以获得更多静态约束是有用的。StaticPtr
不可组合,但Closure
可以。所以distributed-closure
实际做的是定义一个类似的类,我们称之为,
class GimmeClosure c where
gimmeClosure :: Closure (Dict c)
Run Code Online (Sandbox Code Playgroud)
现在我们可以用closurePure
与您类似的方式定义:
closurePure :: (Typeable a, GimmeClosure (Binary a)) => a -> Closure a
Run Code Online (Sandbox Code Playgroud)
如果将来编译器可以GimmeClosure
通过根据需要生成静态指针来即时解决约束,那就太好了。但就目前而言,最接近的是 Template Haskell。分布式闭包提供了一个模块,可以GimmeClosure (Cls a)
在类的定义站点自动生成约束Cls
。看withStatic
这里。
顺便说一句,Edsko de Vries就分布式闭包及其所体现的思想进行了精彩的演讲。
归档时间: |
|
查看次数: |
211 次 |
最近记录: |