简体   繁体   English

省略显式forall会产生模糊类型错误

[英]Omitting explicit forall yields ambiguous type error

I've run into a situation where a function fails to type-check unless I explicitly add a forall to the beginning of its type signature. 我遇到了函数无法进行类型检查的情况,除非我明确地在其类型签名的开头添加了forall。

The function in question is: 有问题的功能是:

test :: (Typeable a) => a -> a
test x 
    | typeOf (undefined :: a) == typeOf (undefined :: a) = x
    | otherwise = x

GHC gives the following warnings on the above: GHC对以上内容发出以下警告:

  Ambiguous type variable `a0' in the constraint:
  (Typeable a0) arising from a use of `typeOf'
Probable fix: add a type signature that fixes these type variable(s)
In the first argument of `(==)', namely `typeOf (undefined :: a)'
In the expression:
  typeOf (undefined :: a) == typeOf (undefined :: a)
In a stmt of a pattern guard for
               an equation for `test':
  typeOf (undefined :: a) == typeOf (undefined :: a)

Ambiguous type variable `a1' in the constraint:
  (Typeable a1) arising from a use of `typeOf'
Probable fix: add a type signature that fixes these type variable(s)
In the second argument of `(==)', namely `typeOf (undefined :: a)'
In the expression:
  typeOf (undefined :: a) == typeOf (undefined :: a)
In a stmt of a pattern guard for
               an equation for `test':
  typeOf (undefined :: a) == typeOf (undefined :: a)

So it's failing to unify the two types of the undefined values. 所以它没有统一两种类型的未定义值。 However if I add a forall a to the front: 但是,如果我在前面添加一个forall:

test :: forall a. (Typeable a) => a -> a
test x 
    | typeOf (undefined :: a) == typeOf (undefined :: a) = x
    | otherwise = x

It compiles fine. 它汇编得很好。 This is in GHC 7.4.2 using 这是在GHC 7.4.2中使用的

{-# LANGUAGE GADTs, StandaloneDeriving, DeriveDataTypeable,
ScopedTypeVariables, FlexibleInstances, UndecidableInstances,
Rank2Types #-}

I was under the impression that omitting "forall" in a type signature was equivalent to implicitly appending foralls to the beginning over all relevant type variables (as suggested in the GHC docs: http://www.haskell.org/ghc/docs/7.4.2/html/users_guide/other-type-extensions.html ). 我的印象是,在类型签名中省略“forall”相当于在所有相关类型变量上隐含地附加了foralls(如GHC文档中所述: http//www.haskell.org/ghc/docs/ 7.4.2 / html / users_guide / other-type-extensions.html )。 Why does the first code fragment not type-check, while the second does? 为什么第一个代码片段不进行类型检查,而第二个代码片段呢?

The ScopedTypeVariables extension adds semantic value to top-level forall quantifiers. ScopedTypeVariables扩展将语义值添加到顶级forall量词。 It is what provides the scoping for the type variable over the body of the binding. 它是在绑定体上提供类型变量的范围。

Without that forall , the type variable a on line 3 is a different type variable than the a on line 1. The error message indicates this by labeling them a0 and a1 . 没有那个forall ,第3行的类型变量a是与第a行的类型变量不同的类型变量。错误消息通过将它们标记为a0a1指示这一点。 Without those being the same type, the type on line 3 is ambiguous, because it is completely unconstrained. 如果没有相同的类型,第3行的类型是模糊的,因为它完全不受约束。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM