如何創建類似於另一個遞歸類型類但具有與「父類」類不同的實例的遞歸類型類?遞歸類型類的子類中的類型類(或遞歸類型的類型)
下面是一個例子:
data Atom = Atom
data (Formula a) => Negation a = Negation a
class Formula a where
instance Formula Atom where
instance (Formula a) => Formula (Negation a) where
class SubFormula a where
instance SubFormula Atom where
這代碼編譯就好了,但是當我加入其轉換超級類型的類的實例函數的子類型類
formulaToSubFormula :: (Formula a, SubFormula b) => a -> b
formulaToSubFormula _ = Atom
之一我得到一個錯誤
test.hs:12:25:
Could not deduce (b ~ Atom)
from the context (Formula a, SubFormula b)
bound by the type signature for
formulaToSubFormula :: (Formula a, SubFormula b) => a -> b
at test.hs:12:1-28
`b' is a rigid type variable bound by
the type signature for
formulaToSubFormula :: (Formula a, SubFormula b) => a -> b
at test.hs:12:1
In the expression: Atom
In an equation for `formulaToSubFormula':
formulaToSubFormula _ = Atom
我最初的目的是用普通的類型來完成這個任務,但是對於類型類來說,這個問題似乎更容易理解,並且通常更加靈活。
例如:
data Formula = Atom | Negation Formula | Conjunction Formula Formula
data SubFormula = Atom | Negation SubFormula
編輯
爲了澄清什麼,我儘量做到:我想驗證的類型級別的輸入類型的操作將只返回一個子集作爲結果的那種類型。
擴展示例(命題邏輯;沒有有效Haskell語法):
data Formula = Atom
| Negation Formula
| Disjunction Formula Formula
| Implication Formula Formula
data SimpleFormula = Atom
| Negation SimpleFormula
| Disjunction SimpleFormula SimpleFormula
-- removeImplication is not implemented correctly but shows what I mean
removeImplication :: Formula -> SimpleFormula
removeImplication (Implication a b) = (Negation a) `Disjunction` b
removeImplication a = a
在以後某個時候我可以具有在合取範式式(沒有有效Haskell語法)
data CNF = CNFElem
| Conjunction CNF CNF
data CNFElem = Atom
| Negation Atom
| Disjunction CNFElem CNFElem
因此我需要一個工具來表示這個層次結構。
請注意,在removeImplication計劃中,您只是刪除最外層的Implication構造函數。 'removeImplication(Negation(Implication x y))'將會是'(Negation(Implication x y))'。一個簡單的解決方案就是擁有兩個'Formula'類型,比如'NormalForm'和一個函數toNormalForm,它通過複數公式並遞歸地將Implications轉換爲合適的NormalForm,不是嗎?我認爲我們仍然需要更多地瞭解你要去哪裏。 – applicative 2011-04-28 00:11:28
@applicative:'removeImplication'函數只是爲了顯示我的意思。事情是,'NormalForm'是'Formula'的一個子集,這就是爲什麼我正在尋找一種方法來在這兩種類型之間共享這個子集。 – 2011-04-28 00:25:12
你的更廣泛的目的是不透明的;例如,是否值得采用其中一種「stephen tetley」提及的途徑。數據類型定義,特別是遞歸類型,就像一個微型語言。你正在考慮幾種小語言及其關係;爲什麼不應該用*類型之間的函數來表達這些關係*?如果'L1'和'L2'是類型,那麼類型'L1-> L2'和'L2-> L1'就是它們之間關係的類型,可以粗暴地說出來。 – applicative 2011-04-29 13:17:16