2016-08-27 64 views
0

考慮下面的代碼片段(來自http://lpaste.net/180651):爲什麼GHC不能推斷出這種類型?

{-# LANGUAGE ScopedTypeVariables #-} 

class Natural n 

newtype V n a = V [a] 

dim :: Natural n => V n a -> Int 
dim = undefined -- defined in my actual code 

bad_fromList :: Natural n => [a] -> V n a 
bad_fromList l = if length l == dim v then v else undefined -- this is line 11 
    where v = V l 

good_fromList :: forall n a. Natural n => [a] -> V n a 
good_fromList l = if length l == dim v then v else undefined 
    where v = V l :: V n a 

GHCI提供了以下錯誤信息:

test.hs:11:33: error: 
    • Could not deduce (Natural n0) arising from a use of ‘dim’ 
     from the context: Natural n 
     bound by the type signature for: 
        bad_fromList :: Natural n => [a] -> V n a 
     at test.hs:10:1-41 
     The type variable ‘n0’ is ambiguous 
    • In the second argument of ‘(==)’, namely ‘dim v’ 
     In the expression: length l == dim v 
     In the expression: if length l == dim v then v else undefined 

爲什麼不能GHCI推斷類型?

或者,在下面的代碼中,純粹的和good_f編譯,而bad_f給出了類似的錯誤消息。爲什麼?

pure' :: Natural n => a -> V n a 
pure' x = v 
    where v = V $ replicate (dim v) x 

bad_f :: Natural n => [a] -> (V n a, Int) 
bad_f xs = (v, dim v) 
    where v = V xs 

good_f :: Natural n => a -> (V n a, Int) 
good_f x = (v, dim v) 
    where v = V $ replicate (dim v) x 
+4

問題是'v'類型'V n a'適用於所有**可能的類型'n'。鑑於Haskell依賴於開放世界的假設,沒有辦法知道應該在那裏使用哪一個'Natural n'實例,因此它說'n0'不明確:'GHC不想選擇一個隨機類型能夠調用dim。你必須讓你的代碼不含糊。 – Bakuriu

+0

這裏的類型實際上並不明確,這些錯誤是由於編譯器試圖推斷比所需的更一般的類型簽名這一事實。如果你啓用了'-XMonoLocalBinds',你的代碼[作品](https://ideone.com/GsEHSO)。 – user2407038

+0

@ user2407038謝謝!使用MonoLocalBinds有什麼缺點嗎? – Kevin

回答

0

正如user2407038建議的那樣,啓用-XMonoLocalBinds可使代碼正常工作。

相關問題