2009-11-21 44 views
0

我總是碰到一個錯誤,但無法理解如何使它正確。這給了我這個錯誤的代碼示例:Haskell類的錯誤我一直都在跌倒,無法理解

class Someclass a where 
    somefunc :: (Num b) => b -> a -> a 

data Sometype = Somecons Int 

instance Someclass Sometype where 
    somefunc x (Somecons y) = Somecons (x+y) 

的錯誤信息是:

無法比擬預期的「B」型反推斷類型「詮釋」
「B」是(')'的第二個參數,即'y'
在'Somecons'的第一個參數中,'somefunc'的類型簽名位於error.hs:3:21
'即'(x + y)'
在expr ession:Somecons

據我所知,錯誤消息試圖告訴我,我使用了一個類型爲Int的名稱,他期望類型爲(Num b)=> b。我無法理解的是Int符合(Num b)=> b。編譯器不應該明白我告訴他什麼(對於這個具體的例子,b應該是一個整數?我怎樣才能使這個合適?

coment: 當然在這個特定的例子中,我可以做一些事情類型簽名:

somefunc :: a -> a-> a 

但supose我想是這樣的:。

data Newtype = Newcons (Int, Int) 

instance Someclass Newtype where 
    somefunc x (Newtype (y,z)) = Newtype (y+x, z) 

事情是這樣的,當我試圖做一些事情在Haskell反覆發生

+0

呵呵......我想你的意思是'data ...'而不是'Data ...' – 2009-11-21 21:16:07

+0

是的,當然。感謝您的更正。 – 2009-11-21 21:45:31

回答

8

那麼,您可以使用universal quantification考慮泛型符號時更清楚一點。因此

somefunc :: (Num b) => b -> a -> a 

意味着什麼,但

somefunc :: forall a b . Num b => b -> a -> a 

這意味着你的類函數必須爲任何數字b定義。

代碼

Data Sometype = Somecons Int 

instance Someclass Sometype where 
    somefunc x (Somecons y) = Somecons (x+y) 

力量b一個具體類型 - Int,不與要求符合的任何數值類型的工作。

您可能希望有這樣的事情

class Num b => SomeClass a b where 
    somefunc :: b -> a -> a 

instance Someclass Somecons Int where 
    -- ... 
5

這個問題可以在+運營商的簽名中可以看出:

(+) :: Num a => a -> a -> a 

正因爲如此,當你在somefunc使用+Int,它令b是一個Int,因此somefunc變爲:

somefunc :: Int -> Sometype -> Sometype 

要實現Someclass類,somefunc預計將有此簽名:

somefunc :: Num b => b -> Sometype -> Sometype 

也就是說,它應該適用於任何類型的實例Num。您的功能只有Int s一起使用。

+1

不會變成':: Int - > Sometype - > Sometype'? – yairchu 2009-11-22 08:20:57

+0

@yairchu,是的,就是這樣,謝謝你的糾正。 – 2009-11-23 04:20:17

3

您不能混用類型,(+) :: a → a → a

let x = 1.2::Double; y=2::Int in x + y 

這已經失敗。

Num是太一般了,如果你指定x::Double你能得到它的一個明確的 '類型轉換' 工作(fromIntegral

instance Someclass Sometype where 
    somefunc x (Somecons y) = Somecons (x + (fromIntegral y)) 

我想你想是這樣的

instance Someclass Sometype where 

    somefunc :: Int → Sometype → Int 
    somefunc x (Somecons y) = Somecons (x + y) 

順便說一句,你需要鍵入數據,而不是數據:-)

+0

箭頭和好的一切,但在哈斯克爾沒有這樣的事情。它是' - >'。 – 2009-11-21 21:38:56

+2

我知道,但在haskell文獻中使用印刷符號是很常見的做法。一些haskell編輯甚至以我展示的方式展示這些符號。 – 2009-11-21 21:48:07

+0

我明白了。我更喜歡' - >',因爲它是可複製的(不是我認爲任何人都會複製粘貼這種人爲的示例代碼)。 – 2009-11-21 21:52:29

1

繼續達里奧的電子xample,你似乎在問什麼是:

class Someclass a where 
    somefunc :: exists b . (Num b) => b -> a -> a 

也就是說,而不是「你選擇一個類型,我的功能將工作」的承諾,"forall b . Num b => b"意味着,你想要的「我會挑類型,所以我的函數將工作「承諾"exists b . (Num b) => b",其中Sr.費爾南德斯提到。 更重要的是,你沒有顯示你的約束(Num b) => b如何幫助你的情況。

真正interestingsituation是:你應該如何處理類以下類型:

data BMephType i o = BMT (i -> (o, BMephType i o)) 
instance Someclass (BMephType (Complex Double -> String) String) where 

最有可能的,你的解決方案將涉及Complex Double。某處。如果它只有涉及Complex Double,並沒有其他Num類型,那麼你正在尋找一種存在型,而不是一個普遍的。