You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中用mypy实现Haskell的RankN类型等价写法?

在Python中结合mypy实现Haskell风格的Rank-N类型

可以实现,你需要调整TypeVar的使用方式,让mypy识别到传入的函数是多态的(即能接受任意符合数值约束的类型并返回同类型),而不是被特化为单一类型。

原代码的问题

你之前用TypeVar("I", int, float)是联合类型绑定的TypeVar,mypy会自动把它特化为范围最宽的类型(这里是float,因为float兼容int),导致f被推断成Callable[[float], float]——所以传入int类型的1会报错,返回值也全是float,不符合预期。

正确实现方式

使用TypeVar的bound参数限定类型范围,并让函数参数的Callable标注体现多态性,对应Haskell里的forall语义:

from typing import Callable, TypeVar
import numbers

# 限定T为所有numbers.Real的子类(int、float都满足)
T = TypeVar('T', bound=numbers.Real)

def rankN(f: Callable[[T], T]) -> tuple[int, float]:
    return (f(1), f(1.0))

代码解释

  • bound=numbers.Real相当于Haskell中Num n的约束,限定T必须是支持数值操作的类型;
  • Callable[[T], T]表示f是一个多态函数:它可以接受任何符合numbers.Real的类型T,返回相同类型的T。mypy会识别到f既能处理int也能处理float,因此返回的元组类型会被正确推断为tuple[int, float]。

测试验证

你可以用以下代码测试,mypy会正确识别返回类型:

# 测试多态函数
result = rankN(lambda x: x * 2)
reveal_type(result)  # mypy输出:Revealed type is "tuple[int, float]"

内容的提问来源于stack exchange,提问作者petrucci4prez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 07:46:06