简体   繁体   English

类型应用程序和约束种类

[英]type applications and constraint kinds

(I'm not entirely familiar with the inner workings of Haskell's constraint solver so this could likely be a rookie question.) (我不完全熟悉Haskell约束求解器的内部工作原理,所以这可能是一个新手问题。)

When trying to use type application on GHC 8.0.1, as shown in the following sample code 尝试在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

it gives me the following errors 它给了我以下错误

• 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

and

• 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 works where there is no constraint involved, but test1 doesn't. test0适用于没有涉及约束的地方,但test1没有。

If you have TypeApplications enabled, you should enable AllowAmbiguousTypes too. 如果您TypeApplications启用,您应该启用AllowAmbiguousTypes了。 If you do so, the error goes away. 如果这样做,错误就会消失。

The ambiguity check rejects definitions t such that no t :: type annotation could ever typecheck. 歧义检查拒绝定义t ,使得t :: type注释无法进行t :: type 检查 For example: 例如:

test1 :: Show a => Int
test1 = 0

If we try to use test1 elsewhere in our program, we find that there's no way to resolve the Show a constraint by way of :: annotation. 如果我们尝试在程序的其他地方使用test1 ,我们发现没有办法通过:: annotation解析Show a constraint。 Therefore the ambiguity check rejects the definition itself. 因此,歧义检查拒绝定义本身。

Of course, with type applications the ambiguity check becomes meaningless (arguably, it should be turned off by default in this case), since test1 @type is fine and completely determined whenever there is a Show type instance available. 当然,对于类型应用程序,歧义检查变得毫无意义(可以说,在这种情况下它应该默认关闭),因为test1 @type很好并且只要有Show type实例可用就完全确定。

Note that this is not the same as the famous show . read 请注意,这与着名的show . read show . read ambiguity. show . read含糊不清。 That still produces an error, with AllowAmbiguousTypes too: 这仍然会产生错误,也有AllowAmbiguousTypes

test2 = show . read 
-- "ambiguous type variable prevents the constraint from being solved"

Operationally, values with c => t types are just functions from c -typed instances to t . 在操作上, c => t类型的值只是从c -typed实例到t Just defining test1 is fine, since we can always define a constant function. 只定义test1很好,因为我们总是可以定义一个常量函数。 However, in show . read 但是,在show . read show . read we need to supply instances as argument (or else there's no code to be run), and there's no way to resolve them. show . read我们需要提供实例作为参数(否则没有代码可以运行),并且没有办法解决它们。 Using test1 without a type application would be similarly ambiguous. 在没有类型应用程序的情况下使用test1也同样含糊不清。

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

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