简体   繁体   English

模式匹配推断类型

[英]Pattern matching inferred type

Why doesn't the below type-check? 为什么不进行以下类型检查? The type of _ is inferred as Double. _的类型推断为Double。

{-# LANGUAGE ScopedTypeVariables, Rank2Types #-}

module Main (main) where

data D a = D a

main =
  let
    n = D (1 :: forall a. (Floating a) => a)
  in
    case n of
      D (_ :: forall a. (Floating a) => a) -> return ()

It appears that the type you are expecting for n is D (forall a. (Floating a) => a) , but that is emphatically not the type that is inferred. 看来,您期望n的类型是D (forall a. (Floating a) => a) ,但着重不是所推断的类型。 In fact, if you try and add that type annotation to n , you will find that GHC will loudly complain. 实际上,如果您尝试将类型注释添加到n ,则会发现GHC会大声抱怨。 Such a type would require GHC to support impredicative polymorphism, and it currently does not (for more information on what that is and why it is complicated, see What is predicativity? ). 这种类型将要求GHC支持强制性多态性,而当前不支持(有关什么是复杂性以及为什么复杂性的更多信息,请参见什么是谓语? )。

The type that is actually inferred for n is D Double . 实际上为n推断的类型是D Double This is actually the result of two things at play: the dreaded monomorphism restriction and Haskell's type defaulting rules. 这实际上是两个因素在起作用的结果:可怕的单态性限制和Haskell的类型默认规则。 Due to the monomorphism restriction, n must be inferred to be a monomorphic type (since it is not syntactically a function and does not have an explicit type annotation). 由于单态性的限制,必须将n推断为单态类型(因为它在语法上不是函数,并且没有显式的类型注释)。 For this reason, D 1 would be ambiguous, since 1 :: forall a. (Floating a) => a 因此, D 1将是模棱两可的,因为1 :: forall a. (Floating a) => a 1 :: forall a. (Floating a) => a is polymorphic. 1 :: forall a. (Floating a) => a是多态的。 However, in this case, Haskell has defaulting rules for numeric types, mostly to avoid the need to resolve ambiguities due to Haskell's polymorphic number literals. 但是,在这种情况下,Haskell具有用于数字类型的默认规则,主要是为了避免由于Haskell的多态数字文字而需要解决歧义。

Since you have explicitly added a type annotation to 1 to make it Floating , then Haskell applies its default rule for floating-point types and defaults to Double . 既然你已经明确添加一个类型注解1让它Floating ,然后哈斯克尔适用于浮点类型,默认为它的默认规则Double Therefore, the type of n is inferred to be D Double . 因此,将n的类型推断为D Double

If you disable the monomorphism restriction, then the type of n would be the slightly more interesting type forall a. Floating a => D a 如果禁用单态限制,则n的类型将是所有a的稍微有趣的类型forall a. Floating a => D a forall a. Floating a => D a , but that is the simpler universally quantified type rather than the existentially quantified one that you want. forall a. Floating a => D a ,但这是您想要的更简单的通用量化类型,而不是现有的量化类型。

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

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