尽管数据处理在别处处理,但功能错误中的非详尽模式
Non-exhaustive pattern in function error despite the data handling being handled elsewhere
我正在尝试编写一种简单的语言,目前我正在尝试实现一个循环,但每次我 运行 程序时,我都会收到一个错误,指出其中有一个非详尽的模式evalStatement_
函数。
----- Main -----
readStatement :: String -> IO [HStatement]
readStatement input = do
program <- readFile input
case parse parseProgram "Olivia" program of
Left err -> fail $ show err
Right parsed -> return $ parsed
evalString :: Env -> String -> IO String
evalString env expr = do
x <- readStatement expr
concat <$> mapM (runIOThrows . liftM show . evalStatement_ env) x
--mapM (runIOThrows . liftM show . evalStatement env) x
-- evalStatement env x
--map (\exprs -> runIOThrows $ liftM show $ evalStatement env exprs) x
--map (runIOThrows $ liftM show $ evalStatement env) x
--runIOThrows $ liftM show $ (evalStatement env x) -- >>= runIOThrows $ liftM show $ evalStatement env
evalAndPrint :: Env -> String -> IO ()
evalAndPrint env expr = do
evalString env expr
return ()
run :: String -> IO ()
run expr = nullEnv >>= flip evalAndPrint expr
main :: IO ()
main = do
args <- getArgs
run $ args !! 0
----- Error -----
Main: Expr.hs:(82,1)-(85,34): Non-exhaustive patterns in function evalStatement_
-----------------
evalStatement_ :: Env -> HStatement -> IOThrowsError ()
evalStatement_ env (Do cond expr) = evalDo env (Do cond expr)
evalStatement_ env (Print val) = do
x <- evalVal env val
liftIO $ putStrLn $ show x
evalDo :: Env -> HStatement -> IOThrowsError ()
evalDo env (Do cond expr) = evalVal env cond >>= \x -> case x of
HBool False -> return ()
HBool True -> do
traverse_ (evalVal env) expr
evalStatement_ env $ Do cond expr
evalVal :: Env -> HVal -> IOThrowsError HVal
evalVal env val @(HInteger _) = return $ val
evalVal env val @(HBool _) = return $ val
evalVal env val @(HString _) = return $ val
evalVal env val @(HList _) = return $ val
evalVal env (Arith x op y) = evalArithmetic env x op y
evalVal env (Assign var val) = evalVal env val >>= defineVar env var
我将错误归结为这些函数。我使用 evalStatement_
来计算 Do
和 Print
函数。我已经测试了 print
并且它确实有效,但我不明白为什么 evalDo
没有。 evalVal
按预期工作,所以我不知道非详尽问题所在的位置。我 运行 使用 -Wall -Wextra
的编译命令,它根据语句数据类型给了我以下内容。
Expr.hs:82:1: warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In an equation for ‘evalStatement_’:
Patterns not matched:
_ (Eval _)
_ (Program _)
|
82 | evalStatement_ env (Do cond expr) = evalDo env (Do cond expr)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...
data HStatement
= Eval HVal
| Print HVal
| Do HVal [HVal]
| Program [HVal]
deriving (Eq, Read)
我不确定为什么 Eval
和 Program
会对一些实际上没有使用它们的东西产生影响,或者我完全遗漏了什么?
您的 main
程序在从您的源文件解析的完整语句列表中按顺序 运行 evalStatement_
显示:
evalString :: Env -> String -> IO String
evalString env expr = do
x <- readStatement expr
concat <$> mapM (runIOThrows . liftM show . evalStatement_ env) x
^^^^ runs on every statement in the list `x`
如果语句列表 x :: [HStatement]
包含任何 Program
或 Eval
语句,那么这将导致 运行 时间错误,因为仅 evalStatement_
处理 Do
和 Print
构造函数。
因此,正如@jpmarinier 评论的那样,如果您希望在任何有效语句上调用 evalStatement_
,那么您需要处理编译器在您打开 -Wall
时警告您的所有情况。
以下缺失案例的定义可能对您有用 运行ning:
evalStatement_ env (Program pgm) = mapM_ (evalStatement_ env) pgm
evalStatement_ env (Eval val) = do
result <- evalVal env val
return ()
请注意 Eval
的大小写非常无用。由于 evalStatement_
不能 return 除了 ()
以外的任何东西,我们最终计算出一个结果然后将其丢弃。这将与刚刚做的几乎一样:
evalStatement_ _ (Eval _) = return () -- do nothing
我正在尝试编写一种简单的语言,目前我正在尝试实现一个循环,但每次我 运行 程序时,我都会收到一个错误,指出其中有一个非详尽的模式evalStatement_
函数。
----- Main -----
readStatement :: String -> IO [HStatement]
readStatement input = do
program <- readFile input
case parse parseProgram "Olivia" program of
Left err -> fail $ show err
Right parsed -> return $ parsed
evalString :: Env -> String -> IO String
evalString env expr = do
x <- readStatement expr
concat <$> mapM (runIOThrows . liftM show . evalStatement_ env) x
--mapM (runIOThrows . liftM show . evalStatement env) x
-- evalStatement env x
--map (\exprs -> runIOThrows $ liftM show $ evalStatement env exprs) x
--map (runIOThrows $ liftM show $ evalStatement env) x
--runIOThrows $ liftM show $ (evalStatement env x) -- >>= runIOThrows $ liftM show $ evalStatement env
evalAndPrint :: Env -> String -> IO ()
evalAndPrint env expr = do
evalString env expr
return ()
run :: String -> IO ()
run expr = nullEnv >>= flip evalAndPrint expr
main :: IO ()
main = do
args <- getArgs
run $ args !! 0
----- Error -----
Main: Expr.hs:(82,1)-(85,34): Non-exhaustive patterns in function evalStatement_
-----------------
evalStatement_ :: Env -> HStatement -> IOThrowsError ()
evalStatement_ env (Do cond expr) = evalDo env (Do cond expr)
evalStatement_ env (Print val) = do
x <- evalVal env val
liftIO $ putStrLn $ show x
evalDo :: Env -> HStatement -> IOThrowsError ()
evalDo env (Do cond expr) = evalVal env cond >>= \x -> case x of
HBool False -> return ()
HBool True -> do
traverse_ (evalVal env) expr
evalStatement_ env $ Do cond expr
evalVal :: Env -> HVal -> IOThrowsError HVal
evalVal env val @(HInteger _) = return $ val
evalVal env val @(HBool _) = return $ val
evalVal env val @(HString _) = return $ val
evalVal env val @(HList _) = return $ val
evalVal env (Arith x op y) = evalArithmetic env x op y
evalVal env (Assign var val) = evalVal env val >>= defineVar env var
我将错误归结为这些函数。我使用 evalStatement_
来计算 Do
和 Print
函数。我已经测试了 print
并且它确实有效,但我不明白为什么 evalDo
没有。 evalVal
按预期工作,所以我不知道非详尽问题所在的位置。我 运行 使用 -Wall -Wextra
的编译命令,它根据语句数据类型给了我以下内容。
Expr.hs:82:1: warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In an equation for ‘evalStatement_’:
Patterns not matched:
_ (Eval _)
_ (Program _)
|
82 | evalStatement_ env (Do cond expr) = evalDo env (Do cond expr)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...
data HStatement
= Eval HVal
| Print HVal
| Do HVal [HVal]
| Program [HVal]
deriving (Eq, Read)
我不确定为什么 Eval
和 Program
会对一些实际上没有使用它们的东西产生影响,或者我完全遗漏了什么?
您的 main
程序在从您的源文件解析的完整语句列表中按顺序 运行 evalStatement_
显示:
evalString :: Env -> String -> IO String
evalString env expr = do
x <- readStatement expr
concat <$> mapM (runIOThrows . liftM show . evalStatement_ env) x
^^^^ runs on every statement in the list `x`
如果语句列表 x :: [HStatement]
包含任何 Program
或 Eval
语句,那么这将导致 运行 时间错误,因为仅 evalStatement_
处理 Do
和 Print
构造函数。
因此,正如@jpmarinier 评论的那样,如果您希望在任何有效语句上调用 evalStatement_
,那么您需要处理编译器在您打开 -Wall
时警告您的所有情况。
以下缺失案例的定义可能对您有用 运行ning:
evalStatement_ env (Program pgm) = mapM_ (evalStatement_ env) pgm
evalStatement_ env (Eval val) = do
result <- evalVal env val
return ()
请注意 Eval
的大小写非常无用。由于 evalStatement_
不能 return 除了 ()
以外的任何东西,我们最终计算出一个结果然后将其丢弃。这将与刚刚做的几乎一样:
evalStatement_ _ (Eval _) = return () -- do nothing