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

Haskell PVP为何判定新增导出函数为非破坏性变更?

Haskell PVP判定新增导出为非破坏性变更的原因解析

代码背景

本地代码

module A where

x :: Int 
x = 5

module Main where

import A
import Lib

main :: IO ()
main = print (x + y)

外部库Lib初始版本(v0.1.0.0)

module Lib where

y :: Int
y = 10

外部库Lib更新版本(v0.1.1.0)

module Lib where

x :: Int
x = -- 任意Int值
y :: Int
y = 10

PVP的判定逻辑

Haskell的包版本政策(PVP)对版本变更的规则定义如下:

  • 主版本号(第一个数字)变更:对应破坏性变更,比如修改/移除原有导出项、类型签名等
  • 次版本号(第二个数字)变更:对应非破坏性的新增操作,比如添加新的导出项、函数、类型
  • 补丁版本(第三、四位):仅用于bug修复,不改动对外API

当Lib从v0.1.0.0升级到v0.1.1.0时,仅新增了x到导出列表,没有修改或删除原有导出的y,完全符合PVP中“次版本号对应非破坏性新增”的规则,因此被判定为非破坏性变更。

原有代码编译失败的原因

原有Main模块使用了无限定导入(import Lib),会导入Lib的所有导出符号。当Lib新增导出x后,Main中的x同时来自A和Lib,触发名称歧义错误。

为什么PVP的断言依然成立

PVP的“非破坏性”是针对遵循规范的库使用方式而言的:

  • 如果用户代码使用显式导入(比如import Lib (y)),只导入需要的符号,就不会出现歧义
  • 如果用户使用限定导入(import qualified Lib as L),通过限定符访问符号,也不会产生冲突

无限定导入所有符号本身是一种脆弱的写法,依赖于库的导出列表不会新增同名符号,这种写法不在PVP承诺兼容的范围内。PVP的设计目标是保证正确使用API的代码可以平滑升级,而非覆盖所有可能的使用场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 04:32:17