【发布时间】:2016-07-06 16:37:25
【问题描述】:
我正在处理具有值(多态,可以是任何值)的控制流数据,并且它还 可以具有一个验证器函数来检查该值是否仍然是好的,并且可以具有“刷新值”的功能(返回具有新值的新数据)。
在原版 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,我需要有两个构造函数,一个用于可刷新数据,另一个用于不可刷新数据。使用可验证的,我需要有 4 个构造函数! (对于可刷新和可验证,对于不可刷新和可验证,对于可验证和不可刷新,以及对于不可刷新和不可验证)。想象一下我以后是否需要另一个可选字段。更糟糕的是:几乎所有字段都是相同的,除了那些正在变化的字段,所以有很多重复。
我还尝试使用类型类/类型族来修正这种情况。
例如,MyData 'Refreshable 'NotValidatable 只是变成了Refreshable data => data,我可以实例化MyData,或者只是删除它以获得可以作为实例的更具体的数据。
这也是有问题的,因为它们不再是真正的字段;即,我不能在没有验证器的情况下获取数据并将其更改为相同的数据 with 验证器(不在类型级别)。
这可能是一个 XY 问题;我认为更简洁的方法是制作Refreshable a 和Validatable a 之类的数据类型并将它们组合在MyData 中,但我不知道该怎么做。我不能把它们包装起来,因为顺序会改变一切。
有没有一种干净的方法可以做到这一点?还是我应该坚持使用 4 个构造函数?或者 Haskell 可能还没有为这类事情做好准备? (没有双关语:P)。
【问题讨论】:
标签: haskell