我正在研究具有值(多态,可以是任何值)的控制流数据,而且它也could有一个验证器函数来检查该值是否仍然有效,并且could有一个“刷新值”的函数(返回具有新值的新数据)。
在 vanilla Haskell 中它可以看起来像这样:
data MyData a = MyData
{value :: a
,validator :: Maybe (a -> Bool)
,refresher :: Maybe (MyData a -> MyData a)}
我真正想要的是这些类型:
data Refreshable = Refreshable | NotRefreshable
data Validatable = Validatable | NotValidatable
MyData (r :: Refreshable) (v :: Validatable)
我已经做到了,但只是与Refreshable
。我想用Validatable
也是,但我在构造函数方面遇到了问题。只为Refreshable
我需要有两个构造函数,一个用于可刷新数据,另一个用于不可刷新数据。有了 validatable,我需要 4 个构造函数! (对于可刷新和可验证、对于不可刷新和可验证、对于可验证和不可刷新、以及对于不可刷新和不可验证)。想象一下我稍后是否需要另一个可选字段。更糟糕的是:除了那些正在变化的字段之外,几乎所有字段都是相同的,因此存在大量重复。
我还尝试用类型类/类型族来修改这种情况。
例如,MyData 'Refreshable 'NotValidatable
就变成了Refreshable data => data
我可以举个例子MyData
或者只是将其删除以获取可以作为实例的更具体的数据。
这也是有问题的,因为它们不再是真正的字段;而是。即我无法在没有验证器的情况下获取数据并将其更改为相同的数据with验证器(不在类型级别)。
这可能是一个 XY 问题;我认为更干净的方法是使数据类型像Refreshable a
and Validatable a
并将它们写成MyData
但我不知道该怎么做。我无法包装它们,因为顺序会改变一切。
有没有一种干净的方法来做到这一点?或者我应该坚持使用 4 个构造函数?或者也许 Haskell 还没有准备好应对此类事情? (没有双关语:P)。