2014-10-05 104 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