Я пытаюсь реализовать функциональность car, cdr, and cons
на языке игрушек, который я пишу, однако, когда я пытаюсь выполнить свою функцию car
через main
, я получаю следующую ошибку:
./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
Удаление many1 letter
в parseOp
переносит ту же ошибку в следующую функцию parseBool
:
parseBool :: Parser HVal
parseBool = many1 letter >>= (\x -> return $ case x of
"True" -> Boolean True
"False" -> Boolean False)