2010-03-24 57 views
2

雖然試圖編譯下面的代碼,讀取從安全包材上readMay其增強版本。「Ambigous型變量」錯誤定製定義當「讀出」功能

readI :: (Typeable a, Read a) => String -> a 
readI str = case readMay str of 
       Just x -> x 
       Nothing -> error ("Prelude.read failed, expected type: " ++ 
           (show (typeOf > (undefined :: a))) ++ 
           "String was: " ++ str) 

我得到一個錯誤從GHC:

WavefrontSimple.hs:54:81:
歧義類型變量'A '中的約束:
'分型一個'
從所產生在src/WavefrontSimple.hs中使用`typeOf':54:81-103
可能的修復:添加修復這些類型變量的類型簽名`

我不明白爲什麼。我應該修正什麼以達到我的意思?

編輯:好的,所以解決方案使用ScopedTypeVariablesforall a在簽名作品。但爲什麼以下產生與上述相似的錯誤?由於使用了asTypeOf :: a -> a -> a,因此編譯器應推斷正確的類型。

readI :: (Typeable a, Read a) => String -> a 
readI str = let xx = undefined in 
      case readMay str of 
       Just x -> x `asTypeOf` xx 
       Nothing -> error ("Prelude.read failed, expected type: " 
           ++ (show (typeOf xx)) ++ 
           "String was: " ++ str) 
+0

我投票在編輯之前投票結束。現在問題已經更新,我相信它不再是重複的,但不能刪除VTC。我想我只能等待它自己過期。 – ephemient 2010-03-25 22:26:52

回答

2

後者不起作用,因爲xx類型是一樣的undefined類型 - 即「FORALL一個一個。」您強制xx與asTypeOf運算符一起使用的具體類型並不意味着它在其他地方的多態性較少。

+0

我相信你是對的。我的理解在你的解釋之前有點不同,我還得改變我的想法。 – Tener 2011-03-01 22:41:50

1

我認爲你需要有範圍的類型變量。

{-# LANGUAGE ScopedTypeVariables #-} 
readI :: forall a. (Typeable a, Read a) => String -> a 
readI str = case readMay str of 
       Just x -> x 
       Nothing -> error ("Prelude.read failed, expected type: " ++ 
           (show (typeOf > (undefined :: a))) ++ 
           "String was: " ++ str) 

See also

+0

哎呀,我應該先查找重複的。這顯然是一個。 – ephemient 2010-03-24 23:08:11

+0

我確實在尋找重複,顯然不夠硬。我的錯。 – Tener 2010-03-25 00:04:32

2

undefined :: areadI :: (Typeable a, Read a) => String -> aa是不一樣的類型a。這就好像你寫了readI :: ... a; readI = ... (undefined :: b)

{-# LANGUAGE ScopedTypeVariables #-} 

readI :: forall a. (Typeable a, Read a) => String -> a 
... 

scoped type variables的擴展名改變Haskell語言以允許您攜帶類型變量a從外範圍內的範圍,若與forall明確地定量。


我不知道爲什麼你的x `asTypeOf` xx似乎沒有工作。這個呢,雖然:

readI :: (Typeable a, Read a) => String -> a 
readI str = xx where 
    xx = case readMay str of 
      Just x -> x 
      Nothing -> error ("Prelude.read failed, expected type: " 
           ++ (show (typeOf xx)) ++ 
           "String was: " ++ str) 
+0

這個問題可能是一個騙局,但這是迄今爲止我見過的最好的解釋。 – 2010-03-25 02:24:07