在Haskell中打印逻辑公式

3

我遇到了一个奇怪的问题。我想编写一个Haskell程序,它可以打印给定的逻辑公式,即:

print (showFormula (I (N (Z 'p')) (A (C (Z 'p') (Z 'q')) (Z 'r'))))

应该打印出类似这样的内容:(其中I表示蕴含,A表示替代,N表示否定,C表示连词,Z表示字符)
"(~p => ((p & q) | r))"

到目前为止,我的代码看起来是这样的:
data Formula
    = Z Char
    | V Bool
    | N Formula
    | C Formula Formula
    | A Formula Formula
    | I Formula Formula
    | Join Formula Formula

showFormula :: Formula -> String
showFormula (Z c) = [c]
showFormula (Join a b) = (showFormula a) ++ (showFormula b)

showFormula (N a) = '~':(showFormula a)
showFormula (C a b) = "("++(showFormula a)++" & "++(showFormula b)++")"
showFormula (A a b) = "("++(showFormula a)++" | "++(showFormula b)++")"
showFormula (I a b) = "("++(showFormula a)++" => "++(showFormula b)++")"

它可以打印正确的字符串,但只有当您输入简单的公式时,例如 (C (Z 'a') (Z 'b')),并且在使用某些扩展公式时会崩溃。我知道问题是将一个公式参数传递给showFormula函数,而不是字符串,但我不知道如何更改。请给我一些建议,如何修复它。


您可能也会喜欢这个目标非常相似的问题 - Daniel Wagner
顺便提一下,如果中缀构造函数以 : 开头,你也可以编写它们,因此你可以使用 Formula :&: FormulaFormula :|: FormulaFormula :=> Formula 代替 CAI。(然后您可能需要固定声明 - 也许是 infixr 3 :&&:infixr 2 :|:infixr 4 :=>。) - Antal Spector-Zabusky
谢谢@AntalS-Z,这很方便,但是需要C、A和I,因为它们是由其他程序生成的。 - bartekmp
2个回答

4

如果您使用-Wall标志编译代码,它将显示以下警告:

fml.hs:4:1: Warning:
    Pattern match(es) are non-exhaustive
    In an equation for `showFormula': Patterns not matched: V _

你忘记写showFormulaV情况,所以如果它到达那里,程序将崩溃,类似于调用空列表的head函数时会崩溃。


就像我刚才说的,我很蠢 :) 谢谢! - bartekmp
3
这并不是愚笨,而只是初学者的错误。 - hugomg

2

看起来你在模式匹配中刚好错过了(V b)这个情况。

data Formula
    = Z Char
    | V Bool
    | N Formula
    | C Formula Formula
    | A Formula Formula
    | I Formula Formula
    | Join Formula Formula

showFormula :: Formula -> String
showFormula (V b) = show b
showFormula (Z c) = [c]
showFormula (Join a b) = (showFormula a) ++ (showFormula b)

showFormula (N a) = '~':(showFormula a)
showFormula (C a b) = "("++(showFormula a)++" & "++(showFormula b)++")"
showFormula (A a b) = "("++(showFormula a)++" | "++(showFormula b)++")"
showFormula (I a b) = "("++(showFormula a)++" => "++(showFormula b)++")"

main :: IO ()
main = do
  print (showFormula (I (N (Z 'p')) (A (C (Z 'p') (Z 'q')) (Z 'r'))))
  -- "(~p => ((p & q) | r))"

我太蠢了...非常感谢你! - bartekmp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接