2014-10-05 93 views
3

我试图为语言E定义一个评估者,并且很坦率地说我完全处于一个茫然的状态,不知道如何解决我一直在获取的如何定义eval类型的所有错误。我花了几个小时阅读口译员,monad,并试图找到类似的东西给我一个基础,但我什么也没有。这是家庭作业,所以自然不要直接给出答案。我现在最大的问题是Num E或Integral E没有实例声明,当我尝试使用fromInt和fromNum来修复这个问题时,我遇到了更多的错误。我也尝试将定义改为各种不同的方式,主要问题是Int与E的类型不匹配。我觉得我错过了一些非常基本的东西,但是我一直无法完全缩小它。如果我不清楚任何特定问题,我会很乐意回答任何其他问题。如果有任何消息来源是很好的附加信息,我真的很感激链接。Haskell迷你语言

data E = IntLit Int 
    | BoolLit Bool 
    | Plus E E 
    | Minus E E 
    | Multiplies E E 
    | Divides E E 
    | Equals E E 
    deriving (Eq, Show) 

eval :: E -> E 
--eval = undefined 
eval (IntLit a) = IntLit a 
eval (BoolLit a) = BoolLit a 
eval (Plus a b) = eval a + eval b 
eval (Minus a b) = eval a - eval b 
eval (Multiplies a b) = eval a * eval b 
eval (Divides a b) = eval a `div` eval b 
eval (Equals a b) = BoolLit(a == b) 
+1

什么都要你'EVAL “真的吗?也许快速看看这个问题/答案(扰流板:我 - 对不起)可以帮助你,因为它似乎是在相同的方向:https://stackoverflow.com/questions/25968409/operations-with-user-defined-datatype/25969082#25969082 – Carsten 2014-10-05 19:39:34

+0

顺便说一句:我认为最有可能的是你应该评估一个'Bool'或者一个'Int',如果你只是在子表达式和模式匹配上进行递归,你可以在'E'本身不使用'+它是评估(是一个“BoolLit”或“IntLit”或其他?我证明这是上面链接的答案。 – Carsten 2014-10-05 19:42:37

+0

对eval的递归调用做得很好 - 你正在考虑沿着正确的路线,所以我因为@CarstenKönig在那里有一个很好的,详细的答案,这就是你需要做的事情。 – AndrewC 2014-10-05 19:44:15

回答

3

Monads与此无关。因为你是混合两种在一起:整数和布尔变量,您可能需要使用某种类型的两轮牛车(GADTs),并定义与输入eval:

eval :: E a -> a 

或定义一个新的类型,称为Value这样的:

data Value = IntValue Int | BoolValue Bool | TypeError 

,然后有:

eval :: E -> Value 

里面的eval,你需要匹配你的表情的结果是这样的:

eval (Plus e1 e2) = case eval e1 of 
    (IntValue v1) -> case eval e2 of 
     (IntValue v2) -> IntValue (v1+v2) 
     _ -> TypeError 
    _ -> TypeError 

这很乏味,但很简单。 :)当然,你不想重复自己很多次,所以通过定义一个辅助功能为自己节省大量的工作:

evalMathBinOp :: (Int -> Int -> Int) -> E -> E -> Value 
evalMathBinOp f e1 e2 = case eval e1 of 
    (IntValue v1) -> case eval e2 of 
     (IntValue v2) -> IntValue (f v1 v2) 
     _ -> TypeError 
    _ -> TypeError 

现在只:

eval (Plus e1 e2) = evalMathBinOp (+) e1 e2 
eval (Minus e1 e2) = evalMathBinOp (-) e1 e2 
-- and so on... 
+0

^^我认为GADT对于这种作业可能有点沉重;)(大多数可能数据类型'E'和'eval'的签名将通过练习来确定 - 它肯定是由这个问题决定的) – Carsten 2014-10-05 19:47:11

+0

是的,这就是为什么我只提到它是如何在现实世界中完成的。 :) – 2014-10-05 19:47:48

+0

感谢您的快速输入!我一定会记住这一点,以防万一我们有更多的余地摆弄未来的问题。 – JustKeepSwimming 2014-10-05 19:51:12