在我的作业中,我必须按如下方式定义逻辑运算符:
使用此数据结构:
data MyBool = Cierto|Falso deriving (Show,Eq) -- Cierto = True and Falso = False
data PQR = A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z deriving (Show,Eq)
data Formula = VarProp PQR
|Neg Formula -- logic not
|Formula :|: Formula -- logic or
|Formula :&: Formula -- logic and... etc
|Formula :->: Formula
|Formula :<->: Formula deriving (Show,Eq)
我必须定义告诉我给定公式是True还是False的函数,例如,如果我写(Cierto :&: Falso)
,答案必须是:Falso
。
根据我的老师的说法,在这种情况下必须调用该函数:&:
并且必须接收MyBool
类型,所以我试图像这样实现:
infixr 3 :&:
(:&:) :: MyBool -> MyBool -> MyBool
Cierto :&: x = x
Falso :&: x = Falso
但是当我尝试加载它时,它说:
Invalid type signature
我不知道我在这里做错了什么。
答案 0 :(得分:5)
问题是函数前面的 :
表示数据构造函数;就像用大写字母开头一样。您应该将:&:
重命名为|&|
。
编辑:没关系,我刚刚意识到你实际想要完成的事情。
:&:
应该花费两个MyBool
并创建一个Formula
而不是另一个MyBool
。您尝试将:&:
实现为函数;它是一个数据构造函数。您已经在data Forumla = ...
表达式中声明了它。
根本不需要函数声明。完全删除以下代码块:
infixr 3 :&:
(:&:) :: MyBool -> MyBool -> MyBool
Cierto :&: x = x
Falso :&: x = Falso
然后,您应该可以使用:&:
获取两个MyBool
并创建Formula
而无需添加任何其他代码。
然而,让:&:
实际对MyBool
采取行动并不够通常。我们希望能够和一起表达和布尔。因此,您实际上希望:&:
合并Formula
。这就是您的代码已经完成的工作。您缺少的是像Literal
这样的构造函数,它接受MyBool
并返回表示该布尔值的Formula
。
答案 1 :(得分:5)
你的教授强迫你为布尔运算符创建一个抽象语法树(AST)。如果你还没有听说过#34;抽象语法树&#34;在此之前,是时候问某人到底发生了什么事。
您实际上想要做的是编写一个类型为eval
的函数(称为Formula -> Formula
})。在查看定义时,我也相信你已经在data Formula
之外留下了一行VarLiteral MyBool
。看起来AST是一种编写在MyBool
上运行的程序的方法,它支持典型的布尔运算以及:->:
assign(?)。
我在Haskell写了几个AST评估员(虽然没有这个老生常谈:)但感觉你的问题中缺少一些。鉴于我面前的情况,我最好的建议就是说这个任务比你想象的更抽象。
最好的运气