在Haskell中定义逻辑运算符

时间:2011-12-05 06:24:39

标签: haskell operators expression typing

在我的作业中,我必须按如下方式定义逻辑运算符:
使用此数据结构:

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

我不知道我在这里做错了什么。

2 个答案:

答案 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评估员(虽然没有这个老生常谈:)但感觉你的问题中缺少一些。鉴于我面前的情况,我最好的建议就是说这个任务比你想象的更抽象。

最好的运气