如何创建类似于另一个递归类型类但具有与“父类”类不同的实例的递归类型类?递归类型类的子类中的类型类(或递归类型的类型)
下面是一个例子:
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