我有一个交易的单子,看起来像:交易类型安全
newtype Transaction t m a = .. my monad stack here ..
t
是我使用,以确保我环比上升适用于同一后台存储的交易幻像类型。
我的主循环的迭代使用类型,如:
Transaction DB IO (Widget (Transaction DB IO()))
上述类型的意思是:“其生成UI窗口小部件,其用户输入转换为交易执行交易”。
此外,我有:
data Property m a = Property { get :: m a, set :: a -> m() }
这是非常有用的(特别是由于它与FCLabels撰写能力
我做一个可怕的很多使用Property (Transaction t m)
产生我的交易。
现在,我想要的类型系统,以保证生成的插件的事务是只读事务和交易Ť他的widget生成被允许为读写事务。
显然,我可以只添加另一个幻象类型的交易,但是这有两个问题:
它需要显式转换从
Transaction ReadOnly
到Transaction ReadWrite
或类型级两轮牛车允许之间的一元组成读和写基元。这我想我可以解决。属性数据构造函数为了包含写入器,总是需要一个读/写操作来强制“m”成为一个ReadWrite事务。我无法在读写和只读事务的上下文中重新使用属性。
我正在寻找一种获得上述类型安全性的好方法,而不会丢失设计的上述特性。
正如您指出的那样,只要具有像'liftRORW :: Transaction ReadOnly t m a - > Transaction ReadWrite t m a'这样的函数,用于跟踪只读/读写的幻像类型可以解决问题。这似乎是一个非常可靠的方法。 我不认为我理解你提出的“财产”问题。 – intoverflow 2010-07-23 00:03:19
改变幻像类型的转换确实很重要,但只需要很少使用。大多数情况下,您可以创建一个函数,该函数可以是幻像类型中免费的ReadOnly或ReadWrite块的一部分。 这是一个穷人的子类型。 – sclv 2010-07-23 01:09:51
此外,您可以更改Property为: 'data Property m a = Property {get :: forall free。 m free a,set :: a - > m ReadWrite()}' 虽然我不知道与那个和FCLabels互操作。 – sclv 2010-07-23 01:15:18