haskell - Haskell 中的布尔非穷举模式
问题描述
我正在 Haskell 中构建一个基本函数,它返回出现在布尔表达式中的变量列表。
出于某种原因,我被困在一个测试用例中。
我还是一个初学者,所以有人可以解释这里发生了什么吗?
这是代码:
module BoolExpr (Variable, BoolExpr(..), evaluate) where
import Data.List
import System.IO
type Variable = Char
data BoolExpr = T
|F
|Var Variable
|Not BoolExpr
|And BoolExpr BoolExpr
|Or BoolExpr BoolExpr
deriving(Show)
-- evaluates an expression
evaluate :: BoolExpr -> [Variable] -> Bool
evaluate T _ = True
evaluate F _ = False
evaluate (Var v) vs = v `elem` vs
evaluate (Not e) vs = not (evaluate e vs)
evaluate (And e1 e2) vs = evaluate e1 vs && evaluate e2 vs
evaluate (Or e1 e2) vs = evaluate e1 vs || evaluate e2 vs
--here is the function
variables :: BoolExpr -> [Variable]
variables (Or T F) = []
variables (And T F) = []
variables (Var a)= [a]
variables (Or (Var a) (Var b)) =[a]++[b]
variables (And (Var a) (Var b))=[a]++[b]
variables T = []
variables F = []
subsets :: [Variable] -> [[Variable]]
subsets [] = [[]]
subsets (x:xs) = [zs | ys <- subsets xs, zs <- [ys, (x:ys)]]
输入:variables (And (Var 'a') (Or (Var 'c') (Var 'b')))
输出:Non-exhaustive patterns in function variables
预期输出:"abc"
其他测试用例:
输入:variables (And (Var 'a') (Or (Var 'a') (Var 'a')))
预期输出:"a"
`
解决方案
如果您打开不完整模式的编译器警告,编译器会告诉您哪些模式不匹配:
Prelude> :set -Wincomplete-patterns
Prelude> :l 58637724.hs
[1 of 1] Compiling BoolExpr ( 58637724.hs, interpreted )
58637724.hs:29:1: warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In an equation for `variables':
Patterns not matched:
(Not _)
(And T T)
(And T (Var _))
(And T (Not _))
...
|
29 | variables (Or T F) = []
| ^^^^^^^^^^^^^^^^^^^^^^^^...
Ok, one module loaded.
将这些案例添加到variables
函数中,问题应该会消失。
...
注意前四个模式后面的省略号 ( )。这表明存在更多不匹配的模式,因此一旦您解决了这四个缺失的模式,请再次查看编译器警告。
推荐阅读
- heroku - Heroku Spring Redis - SessionDestroyedEvent
- python - 解析从 Internet 派生的 XML 文件
- sql - 查询重复记录
- dns - 要启用 DNSSEC,是否需要将域名服务器设置为域注册商?
- c# - 是什么导致 Xamarin Forms 构建上的“无法识别的选择器发送到类”错误?
- java - 将 Json 作为字符串接收并转换为 Java 对象
- firebase - 我们是否为 .validate() 读取收费?
- javascript - [未处理的承诺拒绝:TypeError:未定义不是函数(评估'_expo2.default.loadAsync')]
- sql - SQL 匹配一个字符串后跟一个范围内的数字
- java - Firefox 总是打开 google.com,不管 driver.get 是否指定