Any和Forall a.a是一样的吗?

-3 投票
1 回答
63 浏览
提问于 2025-04-14 18:26

Python 有一个叫做 Any 的类型,它可以和任何类型都兼容。那是不是可以用 Haskell 语言中的 forall a.a 来表示 Any,而不是再添加一个新类型呢?

1 个回答

1

不,它们是不同的。

forall a. a 是一种没有实例的类型。(一个通用类型应该是所有其他类型的并集;而这更像是所有其他类型的交集。)你只能把底层值赋给这种类型的变量:

-- With the ExplicitForAll option set in GHC
x, y :: forall a.a
x = undefined  -- OK
y = 'c' -- Not OK

因此,它是最常用来表示一个函数永远不会返回的类型,这可能是因为它发散(进入无限循环)

> :t let f = f in f
let f = f in f :: t  -- forall t. t

或者因为它抛出了一个异常。

> :t error
error :: [Char] -> t  -- forall t. [Char] -> t

Any 是一种伪类型,它与所有其他类型一致,但并不是任何其他类型的子类型或超类型。

x: Any = 1  # OK
y: Any = 'c' # OK

既然1也不是Any实例,但根据一致性的定义,这样的赋值是被允许的。

在某种意义上,Python 至少在类型检查方面有两个forall a. a等效的类型,分别是typing.NoReturntyping.Never。后者在 Python 3.11 中被引入,作为前者的更清晰替代,但它们在其他方面是等效的。(NoReturn 主要用作返回类型注解,而 Never 明确表示一个空类型,这种类型除了作为不返回函数的返回类型外还有其他用途。NoReturn 似乎已经非正式地被弃用了。)


一致性是将子类型扩展到一个“宇宙”,在这个宇宙中,Any 被添加为一种特殊类型。正如在PEP 483(在渐进类型总结)中所述,

  • 如果类型 t1 是类型 t2 的子类型,那么这两个类型是一致的。(但反过来不成立。)
  • Any 与每种类型都是一致的。(但 Any 不是每种类型的子类型。)
  • 每种类型与 Any 都是一致的。(但每种类型也不是 Any 的子类型。)

撰写回答