haskell - 模式匹配推断类型

标签 haskell pattern-matching higher-rank-types

为什么下面的代码不进行类型检查? _ 的类型被推断为 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 ()

最佳答案

看来是您期望的类型 nD (forall a. (Floating a) => a) ,但这显然不是推断出的类型。事实上,如果您尝试将该类型注释添加到 n ,你会发现GHC会大声提示。这种类型需要 GHC 支持命令式多态性,但目前不支持(有关它是什么以及为什么复杂的更多信息,请参阅 What is predicativity? )。

实际推断出 n 的类型是 D Double 。这实际上是两件事共同作用的结果:可怕的 monomorphism restriction和 Haskell 的类型默认规则。由于单态性限制,n必须推断为单态类型(因为它在语法上不是函数并且没有显式类型注释)。为此,D 1会是不明确的,因为 1 :: forall a. (Floating a) => a是多态的。然而,在这种情况下,Haskell 对数字类型有默认规则,主要是为了避免由于 Haskell 的多态数字文字而需要解决歧义。

由于您已将类型注释显式添加到 1做到Floating ,然后 Haskell 应用其浮点类型的默认规则并默认为 Double 。因此,n的类型推断为 D Double .

如果禁用单态限制,则 n 的类型会是稍微有趣的类型 forall a. Floating a => D a ,但这是更简单的通用量化类型,而不是您想要的存在量化类型。

关于haskell - 模式匹配推断类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41431972/

相关文章:

haskell - 为什么 Haskell 中是 (=<<) id = join ?

list - 试图了解如何不向列表中添加元素

haskell - 为什么 Haskell 标准库中没有 <<?

mysql - MySQL Regexp 是否支持 Unicode 匹配

python - 在 Python 列表中查找模式

dependent-type - 在Idris中进行秩N量化

optimization - Haskell 中的基本列表操作优化

pattern-matching - 模式匹配中 byte_size 的语法是什么?

arrays - 在 STArrays 列表上映射 runSTArray?

haskell - Haskell 中的非法多态或限定类型