我正在编写一个分布式编程 DSL,我希望允许实现选择它们的序列化方法(如果有的话,因为它甚至可能不需要模拟执行)。
尝试通过添加类型族来解决这个问题,导致我拥有的标准函数出现以下问题。我想如果我可以要求它会起作用,并且让类型检查器理解,如果两个值是可序列化的,它们的配对也是可序列化的。但是,将其添加为量化约束似乎不起作用。可以解决这个问题还是有更好的解决方案?
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE TypeFamilies #-}
import Data.Kind
class (Monad (DistrM t)) => Distributed (t :: *) where
type Sendable t :: * -> Constraint
type DistrM t :: * -> *
-- ...
data FromSendable t a where
FromSendable :: (Sendable t b)
=> (b -> DistrM t a)
-> b
-> FromSendable t a
pairWith :: ( Sendable t a
, Distributed t
, forall a b. (Sendable t a, Sendable t b) => Sendable t (a,b)
)
=> a
-> FromSendable t b
-> FromSendable t (a,b)
pairWith a (FromSendable f b) =
FromSendable (\(a,b) -> (a,) <$> f b) (a,b)
-- >>> Could not deduce: Sendable t (a1, b1) ...
编辑 1
它会检查我是否这样做
pairWith :: ( Sendable t a
, Distributed t
, st ~ Sendable t
, forall a b. (st a, st b) => st (a,b)
)
=> ...
必须重复这些类型的约束会很麻烦,所以我尝试了一个类型同义词,但这不起作用:
type Cs t = forall (st :: * -> Constraint).
(Sendable t ~ st, forall a b. (st a, st b) => st (a,b))
-- >>> Expected a constraint, but ‘st (a, b)’ has kind ‘*’