(我并不完全熟悉Haskell的约束求解器的内部工作原理,所以这可能是一个新手问题。)
尝试在GHC 8.0.1上使用类型应用程序时,如以下示例代码所示
{-# LANGUAGE KindSignatures, RankNTypes, ConstraintKinds, ScopedTypeVariables, TypeApplications #-}
module Test where
import Data.Constraint
test0 :: forall (b :: *) . (forall a . a -> Bool) -> b -> Bool
test0 g = g @b
test1 :: forall (c :: * -> Constraint) (b :: *) . (c b) => (forall a . c a => a -> Bool) -> b -> Bool
test1 g = g @b
它给了我以下错误
• Could not deduce: c0 b
from the context: c b
bound by the type signature for:
test1 :: c b => (forall a. c a => a -> Bool) -> b -> Bool
at Test.hs:9:10-101
• In the ambiguity check for ‘test1’
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
In the type signature:
test1 :: forall (c :: * -> Constraint) (b :: *).
(c b) => (forall a. c a => a -> Bool) -> b -> Bool
和
• Could not deduce: c a
from the context: c b
bound by the type signature for:
test1 :: c b => (forall a. c a => a -> Bool) -> b -> Bool
at Test.hs:9:10-101
or from: c0 a
bound by the type signature for:
test1 :: c0 a => a -> Bool
at Test.hs:9:10-101
• In the ambiguity check for ‘test1’
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
In the type signature:
test1 :: forall (c :: * -> Constraint) (b :: *).
(c b) => (forall a. c a => a -> Bool) -> b -> Bool
test0
适用于没有涉及约束的地方,但test1
没有。
答案 0 :(得分:6)
如果您启用了TypeApplications
,则还应启用AllowAmbiguousTypes
。如果这样做,错误就会消失。
ambiguity check拒绝定义t
,因此任何t :: type
注释都无法进行类型检查。例如:
test1 :: Show a => Int
test1 = 0
如果我们尝试在我们的计划中的其他地方使用test1
,我们发现无法通过Show a
注释来解决::
约束。因此,歧义检查拒绝定义本身。
当然,对于类型应用程序,歧义检查变得毫无意义(可以说,在这种情况下默认情况下应该关闭它),因为test1 @type
很好并且只要有Show type
实例就完全确定可用。
请注意,这与着名的show . read
歧义不同。这仍然会产生错误,AllowAmbiguousTypes
也是如此:
test2 = show . read
-- "ambiguous type variable prevents the constraint from being solved"
在操作上,c => t
类型的值只是从c
- 类型实例到t
的函数。只定义test1
很好,因为我们总是可以定义一个常量函数。但是,在show . read
中我们需要提供实例作为参数(否则没有代码可以运行),并且无法解决它们。在没有类型应用程序的情况下使用test1
同样不明确。