2013-02-01 22 views
32

我是Haskell的新手,我正在努力調試我的代碼。 修復錯誤導致其他錯誤...由於使用`/'而沒有出現(Fractional Int)實例

這是我的代碼。

import Data.Maybe 

data Op = Add | Sub | Mul | Div | And | Or | Not | Eq | Less | Great 
    deriving (Eq, Show) 

data Exp = Literal Value 
    | Primitive Op [Exp] 
    | Variable String 
    | If Exp Exp Exp 
    | Let [(String, Exp)] Exp 
    deriving (Show, Eq) 

data Value = Number Int 
     | Bool Bool 
     | String String 
    deriving (Eq, Show) 

type Env = [(String, Value)] 

eval :: Env -> Exp -> Value 
eval e (Literal v) = v 
eval e (Variable x) = fromJust (lookup x e) --22 

prim :: Op -> [Value] -> Value 
prim Add [Number a, Number b] = Number (a + b) 
prim And [Bool a, Bool b] = Bool (a && b) 
prim Sub [Number a, Nuamber b] = Number (a - b) -- No instance for (Fractional Int) arising from a use of `/' 
prim Mul [Number a, Number b] = Number (a * b) 
prim Div [Number a, Number b] = Number (a/b) 
prim Or [Bool a, Bool b] = Bool (a || b) 
prim Not [Bool a] = Bool (not a) 
prim Eq [Number a, Number b] = Bool (a == b) 
prim Eq [String a, String b] = Bool (a == b) 
prim Less [Number a, Number b] = Bool (a < b) 
prim Less [String a, String b] = Bool (a < b) 
prim Great [Number a, Number b] = Bool (a > b) 
prim Great [String a, String b] = Bool (a > b) --37 

main = do 
    eval [("y", (Number 40))] (Let [("x", (Literal (Number 2)))] (prim Add [(Variable "x"), (Variable "y")])) -- Couldn't match expected type `Exp' with actual type `Value' 

我現在收到了兩條我在評論中寫到的錯誤。 如果您知道我的代碼有什麼問題,請分享您的想法並節省我的時間...

非常感謝。

+0

你是不是指'Number(div a b)'或者它的中綴版本? –

回答

52
-- No instance for (Fractional Int) arising from a use of `/' 

據推測這是一個從該線到來而不是一個與您的意見:

prim Div [Number a, Number b] = Number (a/b) 

abInt s。除法運算符爲(/) :: Fractional a => a -> a -> a(可以通過啓動ghci並輸入:t (/)looking it up on Hoogle來查找)。

如果您還沒有看到類型,如Fractional a => a -> a -> a,你應該分兩部分閱讀:

  1. 上下文Fractional a
  2. 類型a -> a -> a

這就像一個普通的a -> a -> a類型,所以它需要一些類型的兩個參數,並返回相同類型的結果。添加Fractional a上下文的唯一區別是用於a的類型必須是Fractional類型類的實例;它不是免費的,可以覆蓋任何你喜歡的類型。

如果您還沒有了解類型類別,請不要擔心。他們很容易掌握,但不是你剛開始時應該深入研究的東西;你稍後會到達他們。

Int不是Fractional類型類的成員,因此/運算符不能在Int s上運行。

原因是正規數學分區不是工作在這種類型的整數; 3/2將不得不給出1.5,在這種情況下,它不適合類型Int -> Int -> Int,或給12,在這種情況下,它不會是正確的數學劃分。有一個功能div用於執行integer division,可用a `div` b中綴表示法。

-- Couldn't match expected type `Exp' with actual type `Value' 

此消息是關於您自己的類型,在您編寫的單個表達式中。實際的完整錯誤信息會給你更多關於表達式的哪一部分包含錯誤的上下文。只需從上到下按順序,自己檢查事物的類型,錯誤很快就會跳出來。

在這種情況下,你在這裏:

Let [("x", (Literal (Number 2)))] (prim Add [(Variable "x"), (Variable "y")]) 

Let需要兩個參數,一個[(String, Exp)]Exp。清單很好,但第二個參數是(prim Add [(Variable "x"), (Variable "y")])。甚至沒有深入到底層結構,看看它是否正確,prim有類型Op -> [Value] -> Value,所以它沒有辦法給你一個Exp

如何解決,這取決於你;看起來您需要在整個表達式/值區分中重構一些。 prim爲您提供了一個Value,您可以簡單地應用Literal中的換行來讓你過去所遇到的類型錯誤,但後來遇到prim應該採用Op[Value]的問題,但是您似乎有給它一個Op和一個[Exp](包含變量)。我想你需要考慮使用prim來計算原始應用程序的結果,使用Primitive的構造函數Exp代表原始應用程序,並使用eval來評估(在環境中)任意表達式(其中可能包含幾個原始應用程序)。

+0

哎呀,我的壞。我把評論放在錯誤的路線上。 – Nayana

+0

非常感謝您抽出寶貴時間回答我的問題。 – Nayana

+0

對不起,但是這個「(/)::分數a => a - > a - > a」是什麼意思?這意味着它需要一個和另一個參數並返回一個,對嗎?但是什麼意思?我怎麼知道這個事實,即Int不是那個分數類型的成員? – Nayana

19

您遇到的問題是Haskell對整數和「分數」除法有不同的功能。整數除法截斷,小數除法不。因此,而不是

prim Div [Number a, Number b] = Number (a/b) 

你想要做

prim Div [Number a, Number b] = Number (a `div` b) 

什麼錯誤消息實際上指的是功能(/)Fractional類的一部分。這基本上是不同類型可以實現的接口。要在它火起來ghci中,做

Prelude> :i (/) 
class Num a => Fractional a where 
(/) :: a -> a -> a 
... 
-- Defined in `GHC.Real' 
infixl 7/

Prelude> :i Int 
data Int = GHC.Types.I# GHC.Prim.Int# -- Defined in `GHC.Types' 
instance Bounded Int -- Defined in `GHC.Enum' 
instance Enum Int -- Defined in `GHC.Enum' 
instance Eq Int -- Defined in `GHC.Classes' 
instance Integral Int -- Defined in `GHC.Real' 
instance Num Int -- Defined in `GHC.Num' 
instance Ord Int -- Defined in `GHC.Classes' 
instance Read Int -- Defined in `GHC.Read' 
instance Real Int -- Defined in `GHC.Real' 
instance Show Int -- Defined in `GHC.Show' 

首先爲您提供有關功能(/)信息獲取的信息:它會告訴你,這是在類Fractional。然後當你:i Int它顯示你所有的實例Int。請注意,Int不是Fractional的實例,因此您不能使用(/)Int

另一個提示:該反引號(')把一個函數轉換成中綴運算符,以便

a `div` b 

相同

div a b 
+0

非常感謝,你有第二個錯誤的想法嗎? – Nayana

+0

那麼,本更快... – Paul

+0

'div'運營商炒鍋我 –

相關問題