Haskell - 非法多态类型?

Haskell - Illegal Polymorphic type?

为什么这个类型单独使用编译通过,放入列表却失败了?

ft1  :: (Foldable t, Num a) => t a -> a
ft1   =   (F.foldl (+)  0)

fTest :: [(Foldable t, Num a) => t a -> a ]
fTest = [ F.foldl (+)  0 ]

后者报错:

folding.hs:80:10:
    Illegal polymorphic or qualified type:
      (Foldable t, Num a) => t a -> a
    Perhaps you intended to use ImpredicativeTypes
    In the type signature for `fTest':
      fTest :: [(Foldable t, Num a) => t a -> a]

同样,尝试命名失败(不同):

type Ftst t a = (Foldable t, Num a) => t a -> a

folding.hs:80:1:
    Illegal polymorphic or qualified type:
      (Foldable t, Num a) => t a -> a
    Perhaps you intended to use RankNTypes or Rank2Types
    In the type declaration for `Ftst'

对 Haskell 的类型系统的这种限制是为了简化类型推断和检查。具有预测等级 1 类型的类型推断(见下文)是可判定的并且具有相对简单的实现。使用 rank-2 类型的类型推断是可判定的,但相当复杂,以至于我不知道任何具有 rank-2 类型推断实现的语言。等级 3 及以上类型的类型推断是完全不可判定的。指示类型也使事情变得相当复杂。 GHC 曾经有一个允许使用非谓语类型进行类型检查(和一些非常有限的推理)的实现,但它太复杂了,后来被淘汰了。 (目前 GHC 仍然接受一些只对指示类型进行类型检查的值,但我认为这不被视为 "stable" 特性。)

快速定义:rank-1 类型具有所有量化和 class 约束 "outside" 类型,因此所有 rank-1 类型都是

形式
forall a_1 ... a_m. (C_1, ..., C_n) => t

Rank-2 类型允许函数参数具有 rank-1 类型;通常 rank n 类型允许函数参数具有 rank (n-1) 类型。

预测性回答了哪些类型可以替代类型变量的问题。如果只能替换单态类型(尽管可能带有类型变量!),则您处于谓词系统中;指示类型允许您用多态类型替换类型变量。通过扩展,谓词系统中的参数数据类型只能接受单态类型作为参数。因此,例如,将 [] 类型构造函数应用于 forall t a. (Foldable t, Num a) => t a -> a 类型的示例试图将构造函数应用于多态类型,因此仅在谓词系统中有效。