我有一個交易的單子,看起來像:交易類型安全
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