如何解决Haskell:If-Block评估程序可在GHCI中正常工作,但通过解析的表达式对其进行评估时则不能
我正在尝试为我的语言编写一个评估器,该评估器使用已分析的if块,评估所有条件并过滤出False分支,然后随机选择一个分支。我现在可以过滤掉分支并留下可能的路径,但仅限于GHCI。当我尝试通过命令行将if块传递到程序中时,发生的情况是,第一个分支为True,这是唯一采用的分支,否则,无论是否有子分支或不。我的二进制表达式求值器正常工作,所以我知道我的错误与if求值器或解析器中的逻辑有关。
这是通过命令行的行为:
~/Desktop/Olivia > ./Main "if (1 > 3)-> 1 + 1 [] (1 < 2)-> 2 + 2"
[]
~/Desktop/Olivia > ./Main "if (1 < 3)-> 1 + 1 [] (1 < 2)-> 2 + 2"
[2]
这是GHCI的行为:
λ > b = SubIf (Expr (HInteger 2) Less (HInteger 1)) [(Expr (HInteger 45) Add (HInteger 45)),(Expr (HInteger 6) Add (HInteger 6))]
λ > c = SubIf (Expr (HInteger 2) Less (HInteger 3)) [(Expr (HInteger 5) Add (HInteger 5)),(Expr (HInteger 6) Add (HInteger 6))]
λ > a = If (Expr (HInteger 3) Less (HInteger 2)) [(Expr (HInteger 1) Add (HInteger 100)),(Expr (HInteger 2) Add (HInteger 2))] [b,c]
λ > eval b -- All False branches return a value of 1
1
λ > eval c
[10 12]
λ > eval a
[[10 12]]
这是我的预期结果。对于n
个子if表达式,在返回评估循环保护并开始程序的下一次迭代之前,我将选择整个列表中的一个列表作为分支。
我的数据类型:
data HVal
= HInteger Integer
| HBool Bool
| HString String
| HList [HVal]
| Expr HVal Op HVal
| EqExpr HVal Op HVal
| Neg HVal
| Assign HVal HVal
| Do HVal [HVal]
| If HVal [HVal] [HVal]
| SubIf HVal [HVal]
| Load String
deriving (Eq,Read)
我的解析器:
parseIf :: Parser HVal
parseIf = do
_ <- string "if"
spaces
_ <- string "("
cond <- (parseExpr <|> parseEqExpr <|> parseBool)
_ <- string ")->"
expr <- spaces *> many (parseExpression <* spaces)
expr' <- spaces *> many (parseExpression <* spaces)
return $ If cond expr expr'
parseSubIf :: Parser HVal
parseSubIf = do
_ <- string "[]"
spaces
_ <- string "("
cond <- (parseExpr <|> parseEqExpr <|> parseBool)
_ <- string ")->"
expr <- spaces *> many (parseExpression <* spaces)
return $ SubIf cond expr
我的评估者:
eval :: HVal -> HVal
---------- EVALUATING PRIMITIVES ----------
eval val@(HString _) = val
eval val@(HInteger _) = val
eval val@(HBool _) = val
eval val@(HList _) = val
eval (Expr x op y) = evalExpr x op y
eval (If cond expr expr') = evalIf cond expr expr'
eval (SubIf cond expr) = evalSubIf cond expr
evalIf :: HVal -> [HVal] -> [HVal] -> HVal
evalIf cond expr expr' = if ((eval cond) == (HBool True))
then HList $ map eval expr
else HList $ (filter (/= (HInteger 1)) (map eval expr'))
evalSubIf :: HVal -> [HVal] -> HVal
evalSubIf cond expr = if ((eval cond) == (HBool True))
then HList $ map eval expr
else (HInteger 1)
我认为该错误可能与我的if块解析器有关。我的想法是,if块包含第一个分支的条件及其要求值的内容,然后是一个子表达式列表,其中列表中的每个元素都包含条件分支及其求和的条件。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。