2016-03-11 104 views
0

我想研究haskell中的類型類。我寫了下面的腳本,並提出了一個錯誤。我無法理解爲什麼編譯器將v視爲具體類型,而它只是Boxer類的參數。爲什麼編譯器在下面的haskell代碼上出錯?

data Box1 a b = Box1 Double a [b] 

class Boxer v where 
    foo :: (v a b) -> Double 

instance Boxer (Box1 a b) where 
    foo (Box1 r s t) = r 

它在第7行引發錯誤:8:

Couldn't match type `v' with `Box1' 
    `v' is a rigid type variable bound by 
     the type signature for foo :: v a b -> Double at file1.hs:4:10 
Expected type: v a b 
    Actual type: Box1 a b 
Relevant bindings include 
    foo :: v a b -> Double (bound at file1.hs:7:3) 
In the pattern: Box1 r s t 
In an equation for `foo': foo (Box1 r s t) = r 
Failed, modules loaded: none. 
+0

在這種情況下,錯誤可能是由於壓痕 - 在'foo'聲明不與'Boxer'類相關聯,因此,預計類型的函數'FORALL V A灣v a b - > Double'。除此之外,'實例Boxer(Box1 a b)'不正確 - 它應該是'實例Boxer Box1'。如果'foo'函數與'Boxer'類正確關聯,前者將是一個類型錯誤。 – user2407038

+0

@ user2407038非常感謝。這確實是由於縮進而導致的錯誤。 但是,請你解釋一下,當我創建一個Foldable的實例時,那裏的編譯器不讓我做實例Foldable Box1。它要求在Box1上放置更多參數。 –

+0

您必須編寫'Foldable(Box1 a)'實例'''Foldable'類需要'* - > *'類的參數,而'Box1'類是'* - > * - > *'。 – user2407038

回答

1

特別的問題是由不正確的縮進造成的。雖然還有一件事我做錯了。所以下面的版本編譯:

data Box1 a b = Box1 Double a [b] 

class Boxer v where 
    foo :: (v a b) -> Double 

instance Boxer Box1 where 
    foo (Box1 r s t) = r 
2

在您的實例,編譯器實例vBox1 a b。尤其是,它必須實例化v a b(Box1 a b) a b –之類的東西,除了兩個a變量來自不同的地方;他們實際上被歧義化爲(Box1 a b) a1 b1。這與Box1 a b a1 b1相同。

foo :: Box1 a b a1 b1 -> Double 

這是否有意義?

的問題是,你是一個混亂(類型)功能,即Box1,隨着應用的結果說功能某種類型的參數。該不匹配:

GHCi> :k Boxer 
Boxer :: (* -> * -> *) -> Constraint 
GHCi> :k (Box1 Int String) 
Box1 Int String :: * 

* -> * -> *是那種有兩個參數的函數類型/類型構造的,所以這就是Boxer需求。而Box1 a b只是一個類型,沒有參數。不匹配! OTOH,

GHCi> :k Box1 
Box1 :: * -> * -> * 
+0

這解決了代碼中的語義錯誤,但OP中的類型錯誤是由於原始代碼中的不正確縮進引起的。 – user2407038

相關問題