Haskell : 函数中的非穷尽模式阻止另一个函数执行,即使它没有被使用
Haskell : Non-Exhaustive Pattern In Function Prevents Another Function From Executing Even Though Its Not Used
我正在尝试将 car, cdr, and cons
功能实现到我正在编写的玩具语言中,但是当我尝试通过 main
执行我的 car
功能时,出现以下错误:
./parser "car [1 2 3]"
parser: parser.hs:(48,27)-(55,45): Non-exhaustive patterns in case
第 48-55 行的函数如下:
parseOp :: Parser HVal
parseOp = (many1 letter <|> string "+" <|> string "-" <|> string "*" <|> string "/" <|> string "%" <|> string "&&" <|> string "||") >>=
(\x -> return $ case x of
"&&" -> Op And
"||" -> Op Or
"+" -> Op Add
"-" -> Op Sub
"*" -> Op Mult
"/" -> Op Div
"%" -> Op Mod)
我真的不确定为什么错误消息指向这个函数,因为它与列表功能无关。然而 car
函数正在运行,因为我能够通过 GHCI
成功执行它。我知道我的问题是由于解析引起的,但我看不到它在哪里。以下是与列表相关的函数。我从他们身上看不出他们是如何受到parseOp
.
影响的
data HVal = Number Integer
| String String
| Boolean Bool
| List [HVal]
| Op Op
| Expr Op HVal HVal
| Car [HVal]
deriving (Read)
car :: [HVal] -> HVal
car xs = head xs
parseListFunctions :: Parser HVal
parseListFunctions = do
_ <- string "car "
_ <- char '['
x <- parseList
_ <- char ']'
return $ Car [x]
parseExpr :: Parser HVal
parseExpr = parseNumber
<|> parseOp
<|> parseBool
<|> parseListFunctions
<|> do
_ <- char '['
x <- parseList
_ <- char ']'
return x
<|> do
_ <- char '('
x <- parseExpression
_ <- char ')'
return x
eval :: HVal -> HVal
eval val@(Number _) = val
eval val@(String _) = val
eval val@(Boolean _) = val
eval val@(List _) = val -- Look at list eval NOT WORKING
eval val@(Op _) = val
eval (Expr op x y) = eval $ evalExpr (eval x) op (eval y)
eval (Car xs) = eval $ car xs
在parseOp
中删除many1 letter
将相同的错误传递给以下函数parseBool
:
parseBool :: Parser HVal
parseBool = many1 letter >>= (\x -> return $ case x of
"True" -> Boolean True
"False" -> Boolean False)
你写
parseExpr = ... <|> parseOp <|> ... <|> parseListFunctions <|> ...
等等
car ...
先传给parseOp
,然后parseListFunctions
。 parseOp
解析器在
中成功
many1 letter
分支,所以在\x -> return $ case x of ...
,x
绑定到"car"
。因为 parseOp
成功(并且 returns 一个带有嵌入的错误值,not-yet-evaluated 不穷尽的大小写错误!),parseListFunctions
从未尝试过。
您将需要修改语法以减少其中的歧义,这样就不会出现多个分支可能匹配的冲突。
我正在尝试将 car, cdr, and cons
功能实现到我正在编写的玩具语言中,但是当我尝试通过 main
执行我的 car
功能时,出现以下错误:
./parser "car [1 2 3]"
parser: parser.hs:(48,27)-(55,45): Non-exhaustive patterns in case
第 48-55 行的函数如下:
parseOp :: Parser HVal
parseOp = (many1 letter <|> string "+" <|> string "-" <|> string "*" <|> string "/" <|> string "%" <|> string "&&" <|> string "||") >>=
(\x -> return $ case x of
"&&" -> Op And
"||" -> Op Or
"+" -> Op Add
"-" -> Op Sub
"*" -> Op Mult
"/" -> Op Div
"%" -> Op Mod)
我真的不确定为什么错误消息指向这个函数,因为它与列表功能无关。然而 car
函数正在运行,因为我能够通过 GHCI
成功执行它。我知道我的问题是由于解析引起的,但我看不到它在哪里。以下是与列表相关的函数。我从他们身上看不出他们是如何受到parseOp
.
data HVal = Number Integer
| String String
| Boolean Bool
| List [HVal]
| Op Op
| Expr Op HVal HVal
| Car [HVal]
deriving (Read)
car :: [HVal] -> HVal
car xs = head xs
parseListFunctions :: Parser HVal
parseListFunctions = do
_ <- string "car "
_ <- char '['
x <- parseList
_ <- char ']'
return $ Car [x]
parseExpr :: Parser HVal
parseExpr = parseNumber
<|> parseOp
<|> parseBool
<|> parseListFunctions
<|> do
_ <- char '['
x <- parseList
_ <- char ']'
return x
<|> do
_ <- char '('
x <- parseExpression
_ <- char ')'
return x
eval :: HVal -> HVal
eval val@(Number _) = val
eval val@(String _) = val
eval val@(Boolean _) = val
eval val@(List _) = val -- Look at list eval NOT WORKING
eval val@(Op _) = val
eval (Expr op x y) = eval $ evalExpr (eval x) op (eval y)
eval (Car xs) = eval $ car xs
在parseOp
中删除many1 letter
将相同的错误传递给以下函数parseBool
:
parseBool :: Parser HVal
parseBool = many1 letter >>= (\x -> return $ case x of
"True" -> Boolean True
"False" -> Boolean False)
你写
parseExpr = ... <|> parseOp <|> ... <|> parseListFunctions <|> ...
等等
car ...
先传给parseOp
,然后parseListFunctions
。 parseOp
解析器在
many1 letter
分支,所以在\x -> return $ case x of ...
,x
绑定到"car"
。因为 parseOp
成功(并且 returns 一个带有嵌入的错误值,not-yet-evaluated 不穷尽的大小写错误!),parseListFunctions
从未尝试过。
您将需要修改语法以减少其中的歧义,这样就不会出现多个分支可能匹配的冲突。