我一直在玩Cloud Haskell。我注意到in the hackage documentation有一种应用程序界面。但特别是我正在尝试查找或编写具有以下签名的函数closurePure
:
closurePure :: (Typeable a, Binary a) => a -> Closure a
这基本上是pure的受限版本。
尽管
Closure
数据类型本身是抽象的,但提供了以下 closure
:closure :: Static (ByteString -> a) -> ByteString -> Closure a
所以我可以做到这一点:
closurePure :: (Typeable a, Binary a) => a -> Closure a
closurePure x = closure ??? (encode x)
问题是将
???
放在哪里。我的第一次尝试是:
myDecode :: (Typeable a, Binary a) => Static (ByteString -> a)
myDecode = staticPtr (static decode)
但是在阅读GHC docs on static pointers时,
show
示例向我建议您没有约束,因为受约束的函数没有Typeable
实例。所以我尝试了建议使用 Dict
的方法:myDecode :: Typeable a => Static (Dict (Binary a) -> ByteString -> a)
myDecode = staticPtr (static (\Dict -> decode))
但是现在我得到了上面的
closure
函数不适合的错误类型。无论如何,有没有要写
closurePure
或类似的东西(或者我在Cloud Haskell文档中错过了它)?对于使用给定的应用程序接口(interface),将binary
普通类型提高为Closure
似乎很重要,但是我不知道该怎么做。请注意,我可以这样做:
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)
效果很好,但基本上需要我为每个
Binary
实例重复一个实例。看起来很乱,我更喜欢另一种方式。 最佳答案
没错,Closure
具有类似应用程序的结构,事实在distributed-closure的接口(interface)和实现中都更加明确。它不是很实用,因为在pure
情况下,我们确实具有附加约束,即该参数必须以某种方式可序列化。
实际上,我们有更严格的约束。该参数不仅必须可序列化,而且约束本身也必须可序列化。就像很难直接序列化函数一样,您可以想象很难序列化约束。但是就像函数一样,技巧是将静态指针序列化为约束本身(如果存在)。我们怎么知道这样的指针存在?我们可以用一个方法引入一个类型类,该方法在给定约束的情况下为我们提供了指针的名称:
class GimmeStaticPtr c where
gimmeStaticPtr :: StaticPtr (Dict c)
这里有一个小技巧。
StaticPtr
的类型索引的类型为*
,而约束条件为Constraint
。因此,我们重用了constraints库中的技巧,该技巧包括将约束包装到数据类型中(上面的Dict
),就像所有数据类型一样,它都是*
。具有关联的GimmeStaticPtr
实例的约束称为静态约束。通常,组合静态约束以获得更多的静态约束有时很有用。
StaticPtr
是不可组合的,但Closure
是可组合的。所以distributed-closure
实际要做的是定义一个类似的类,我们将其称为“class GimmeClosure c where
gimmeClosure :: Closure (Dict c)
现在,我们可以按照与您相似的方式定义
closurePure
:closurePure :: (Typeable a, GimmeClosure (Binary a)) => a -> Closure a
如果将来,编译器可以通过根据需要生成静态指针来即时解决
GimmeClosure
约束,那就太好了。但是现在,最接近的是Template Haskell。分布式闭包提供了一个模块,用于在类GimmeClosure (Cls a)
的定义站点上自动生成Cls
约束。参见withStatic
here。顺便说一句,埃德斯科·德弗里斯(Essko de Vries)发表了关于分布式封闭及其体现的思想的书。
关于haskell - Cloud Haskell-如何为闭包编写 "pure"?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47724724/