2017-01-30 61 views
1

什麼我目前要做的是創建一個名爲Value類型:匹配預期型

data Value = Num Int 
      | Sum Int Int 
      | Dif Int Int 
      | Neg Int 
       deriving (Eq) 

與我要實現一個eval函數:

eval :: Value -> Int 
eval (Num x) = x 
eval (Sum x y) = x + y 
eval (Dif x y) = x - y 
eval (Neg x) = -x 

我的預期結果應該是:

eval $ Dif (Sum (Num 3) (Num 6)) (Neg 4) 
> 13 

與我目前的代碼我能夠測試每個操作員themselve他們的功能。

eval (Dif 3 4) 
>-1 

當我嘗試在預期輸入進行嵌套操作上面,我再拿到錯誤的問題出現了:

"Couldn't match expected type Int with actual type Value "

我想,因爲我以爲我的操作來理解問題應該返回一個Int,因爲我的Value類型採用Int,下一個操作應該具有預期的類型。我一直在測試各種輸入,看看有什麼我目前的eval函數實際上做的和發現,如果我做

eval (Dif (eval (Sum 3 5)) 4) 
>4 

我得到預期的結果。我在這裏做錯了什麼?

+0

你爲什麼要把'Value'放到需要'Int'的東西里? 'Sum(Num 1)(Num 2)''不起作用,因爲'Num 1 :: Value'但'Sum'需要'Int'。 – AJFarmar

+1

除了你得到的正確答案之外,你可能想要考慮讓'Value'成爲'Num'的一個實例 - 這樣你就可以編寫'1 :: Value'。 – Alec

+1

我完全忽略了,我實際上正在使用Value類型;我錯誤的思維AJFarmer(我會責怪它缺乏睡眠)。我的文章被編輯了,但我是Haskell的新手,所以我屈服於簡單的錯誤。感謝亞歷克的提示! – Sinsarii

回答

6
data Value = Num Int 
      | Sum Int Int 
      | Dif Int Int 
      | Neg Int 

這裏你指定的Value構造上Int值只工作,例如,Neg有型Int -> Value。所以你不能寫Neg (Neg 1)Sum (Num 1) (Num 2)之類的東西,因爲你試圖使用標籤Value,其中未標記Int預計。在Lisp中,當函數只需要1時,就好像你通過了(Num . 1)

你可以改變你的類型的定義接受Value

data Value = Num Int 
      | Sum Value Value 
      | Dif Value Value 
      | Neg Value 

現在這個代表表達式,其中Num是文字Int但其他構造上Value s運行。然後eval功能相應改變:

eval :: Value -> Int 
eval (Num x) = x 
eval (Sum x y) = eval x + eval y 
-- ... 
+1

謝謝!我只是重新閱讀本節,並意識到我所做的一切。謝謝你的解釋! – Sinsarii

相關問題