首页 文章

定义自定义“读取”功能时出现“Ambigous type variable”错误

提问于
浏览
2

在尝试编译以下代码时,这是来自Safe包的readMay上的read build的增强版本 .

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'产生的Typeable a':54:81-103可能的修复:添加类型签名修复了这些类型变量`

我不明白为什么 . 得到我的意思应该修复什么?

EDIT: 好的,所以在类型签名中使用 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)

3 回答

  • 2

    我认为你需要范围类型变量 .

    {-# 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 .

  • 1

    后者不起作用,因为 xx 的类型与 undefined 的类型相同 - 即"forall a. a."强制xx与asTypeOf运算符一起使用的事实并不意味着它的多态性较小在其他地方 .

  • 2

    undefined :: areadI :: (Typeable a, Read a) => String -> a 中的 aa 的类型不同 . 就像你写了 readI :: ... a; readI = ... (undefined :: b) 一样 .

    {-# LANGUAGE ScopedTypeVariables #-}
    
    readI :: forall a. (Typeable a, Read a) => String -> a
    ...
    

    scoped type variables扩展名更改Haskell语言,以允许您将类型变量 a 从外部作用域携带到内部作用域,如果使用 forall 明确量化的话 .


    我不确定为什么你的 xasTypeOfxx 似乎不起作用 . 但这确实如此:

    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)
    

相关问题