2010-03-24 42 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