如何在Haskell中生成函数的字符串表示?自定义布尔函数打印方法问题
问题原因
你遇到的报错是因为Haskell不支持对函数值进行模式匹配。Haskell中的函数是不透明的抽象值,运行时没有身份标识,既不能判断两个函数是否相等,也不能通过模式匹配区分不同的函数定义。
你在repr函数参数位置写的and'、or'等并不是引用你之前定义的全局布尔函数,而是被识别成了新的局部参数变量,第一个分支会匹配所有输入,所以后续分支全是冗余的,不管你传什么函数都会返回"and"。
解决方案1:使用代数数据类型(ADT)封装操作(最推荐)
这是Haskell中处理这类需求的标准做法,把所有布尔操作定义为代数类型的构造子,再单独绑定求值逻辑和字符串表示:
-- 定义所有布尔操作的枚举类型 data BoolOp = And | Or | Nand | Nor | Xor | Impl | Equ deriving (Eq, Show) -- 实现操作的求值逻辑 eval :: BoolOp -> Bool -> Bool -> Bool eval And p q = p && q eval Or p q = p || q eval Equ p q = p == q -- 剩余操作按规则补充即可 -- 实现操作到字符串的映射 repr :: BoolOp -> String repr And = "and" repr Or = "or" repr Equ = "equivalent to" -- 剩余操作的字符串表示补充即可
使用示例:
-- 生成 "True or False is True" 的示例 a = True b = False op = Or exprStr = show a ++ " " ++ repr op ++ " " ++ show b ++ " is " ++ show (eval op a b)
解决方案2:把函数和名称打包成记录类型
如果你希望直接拿到可调用的函数实例,也可以把函数和对应的名称封装在同一个记录类型里:
data Predicate = Predicate { getName :: String -- 对应的字符串表示 , apply :: Bool -> Bool -> Bool -- 实际的布尔函数实现 } -- 定义各个布尔谓词 and' :: Predicate and' = Predicate "and" (&&) or' :: Predicate or' = Predicate "or" (||) equ' :: Predicate equ' = Predicate "equivalent to" (==)
使用时直接调用对应字段即可:
-- 取字符串表示 getName equ' -- 输出 "equivalent to" -- 调用函数 apply equ' True True -- 输出 True
内容的提问来源于stack exchange,提问作者Andrey Kachow
相关产品推荐
相关产品推荐

