深入解析 Unison 的类型声明:结构类型、唯一类型与不透明类型的演进之路

发布时间:2026/10/8 19:19:08
深入解析 Unison 的类型声明:结构类型、唯一类型与不透明类型的演进之路 编程语言编译器语言运行时开发工具【免费下载链接】unisonA friendly programming language from the future项目地址https://gitcode.com/gh_mirrors/un/unison点击查看免费下载导读docs/type-declarations.markdown是 Unison 语言设计早期标记为 draft的一份核心设计文档它系统性地讨论了三种数据类型声明形态——结构类型Structural Types、唯一类型Unique Types与不透明类型Opaque Types——各自的身份identity定义方式、构造子唯一性约束、模块化封装能力以及三者之间的组合可能性。本文以该文档为主线结合当前仓库中的 DataDeclaration 实现、V2 哈希实现 与词法器源码还原这些设计决策的来龙去脉并对照>data DataDeclaration v a DataDeclaration { annotation :: a, bound :: [v], constructors :: [(a, v, AnnotatedType v a)] -- isStructural :: IsStructural -- isOpaque :: Set (AnnotatedTerm v a) } deriving (Eq, Show, Functor) -- type IsStructural Structural | Unique GUID这段草稿代码与当前仓库中的最终实现高度对应。在 unison-core/src/Unison/DataDeclaration.hs#L115-L121 中DataDeclaration已被整理为data DataDeclaration v a DataDeclaration { modifier :: Modifier, annotation :: a, bound :: [v], constructors :: [(a, v, Type v a)] } deriving (Eq, Ord, Show, Functor, Generic)草稿中被注释掉的isStructural :: IsStructural与isOpaque :: Set (AnnotatedTerm v a)正是对类型身份由什么决定这一核心问题的探索痕迹最终它们收敛为一个独立的Modifier代数数据类型data Modifier Structural | Unique Text -- | Opaque (Set Reference) deriving (Eq, Ord, Show)在 V2 哈希模块 中Modifier的定义与之一致而注释中的Opaque (Set Reference)也原样保留——这说明不透明类型在当时仍是悬而未决的候选方案尚未进入最终的类型系统。从源码结构可以推断Opaque 在正式实现中并未落地Unique 则通过 GUIDText实现Structural 成为默认形态。类型身份为什么如此重要文档虽然没有长篇展开背景但配套文档>structural type Maybe a Nothing | Just a structural type Optional t Some t | None由于结构类型的身份完全由构造子的结构签名决定Maybe与Optional是同一个类型。更进一步structural type Validation e a Success a | Failure e structural type Either a b Left a | Right b即使语义上并不应该等同Validation与Either的语义差异明显它们仍然会因结构相同而互通——文档指出这也许本不该如此属于设计上需要接受的现实。配套文档>unique type Day Mon | Tue | Wed | ... unique[guid] type Day Mon | Tue | Wed | ...从解析器源码可以印证 GUID 的两种来源路径Parser.hs#L200-L204 中解析环境带有一个uniqueTypeGuid :: Name - m (Maybe Text)回调——每当遇到未显式指定 GUID 的unique type声明时先按名字查询是否已有可复用的 GUIDJust则复用否则调用uniqueName 32生成一个 32 字符的 base32hex 随机标识。这与文档中GUID 通常自动生成、但可显式指定以复用相同类型的设计完全吻合。构造子的有序性问题文档给出了一个在当时仍未敲定的细节Order of constructors having the same type is stable, but the relative constructor order of differently typed constructors is (currently) unspecified.即同类型构造子之间的相对顺序是稳定的而不同类型构造子的相对顺序当时未定义。对比>opaque type Socket Socket Nat opaque type Handle Handle Text文档随即抛出两个尚待解答的问题如何声明一个能检查两种不透明类型的定义我们自己语言实现者如何创建和检查 Socket不想公开访问器但又需要某种方式让特权代码构造这些值——单构造子类型较简单多构造子情形可能需要一种确定性的区分方式。与 Scala 不透明类型的对比文档引用了 Scala SIPopaque types作为参照并记录了三点观察Scala 的不透明类型本质上是类型别名无装箱只在对应的伴生对象/模块内部相等Unison 则需要把值装箱进构造子以获得与类型身份对应的哈希因此两者在实现机制上存在本质差异。另一种思路friend 注解与私有函数文档随后记录了一条来自社区讨论的替代方案线索指向 2019 年的 Slack 讨论文内附有链接与其强制改变类型身份才能添加特权函数这有违开放世界精神不如让不透明类型的身份完全等同唯一类型再额外允许将某些项标注为某类型的friend从而获准创建/模式匹配其值。草案给出如下语法friend[Foo, Bar] eg : Foo Bar eg Foo.Foo 1 hi (Bar.Bar 3.1) -- syntax reminiscent of unique[#af361]这种注解是挂在项上的元数据语言可以提供列出某个类型的所有 friend的能力以评估特权代码的足迹footprint。在此基础上文档进一步提出private[Foo]注解它既蕴含friend[Foo]又限定只能被其他friend[Foo]项引用。理由是仅靠控制创建 模式匹配并不足以覆盖前述三个模块化目标——库内部的辅助函数仍可能被以破坏不变量的方式调用或将来被改动/移除或与 API 不在同一语义层级。实现现状Opaque 未落地需要如实指出从当前仓库源码看不透明类型并未作为独立语言特性实现。Modifier中Opaque (Set Reference)仅存在于注释里见 unison-core/src/Unison/DataDeclaration.hs#L105 与 unison-hashing-v2/src/Unison/Hashing/V2/DataDeclaration.hs#L29。仓库中opaque字样多数指向运行时内部的Canonicalizer值如 unison-runtime/src/Unison/Runtime/Canonicalizer.hs#L114与语言层面不透明数据类型是两回事。内置类型如MVar的伪不透明是通过Reference.Builtin机制实现的详见 adding-builtins.markdown 中对builtinTypesSrc与B MVar CT.Data的说明——那是另一条实现路径内置引用 名称合并而非用户级的不透明类型语法。组合规则哪些形态可以叠加文档用一张简明的表回答了组合问题组合结论说明Structural Unique否身份机制互斥Structural Opaque否身份机制互斥Unique Opaque可以Opaque 隐含 Unique由此得到关键推论Opaque 蕴含 Unique。文档给出的判别用例极具指导性需要Opaque 但不需 Unique的场景SortedSet——其语义完全由暴露的方法定义两个实现相同方法的集合类型可以视为同一类型需要Unique Opaque的场景Socket、Handle——暴露的方法决定了这两个类型必须保持不同身份即使内部表示相同。这一组合矩阵与Modifier Structural | Unique Text的最终落地形态一致一旦 Opaque 落地它必然建立在 Unique 之上。遗留的设计讨论构造子顺序与代数类型构造子显示顺序应作为可编辑元数据文档记录了一个真实场景一位开发者为了可读性把IsOptional类型的构造子从Optional / Required / ZeroPlus / OnePlus调整为Optional / Required / ZeroPlus / OnePlusRequired 提前但语义完全没变仍希望这是同一个类型——而当时提出的所有类型实现都无法做到这一点。作者Paul Chiusanopchiusano的回应是构造子显示顺序应作为附着在类型声明上的元数据允许被编辑add/update命令在默认情况下甚至可以针对这类修改建议元数据编辑。这个讨论最终如何收场可以参考>赞分享编程语言编译器语言运行时开发工具【免费下载链接】unisonA friendly programming language from the future项目地址https://gitcode.com/gh_mirrors/un/unison点击查看免费下载相关推荐Roc 编译器局部类型声明详解块级作用域的类型别名、名义类型与不透明类型Roc 编译器局部类型声明详解块级作用域的类型别名、名义类型与不透明类型 本文基于 roc 语言仓库中的编译快照测试 test/snapshots/type_PHP-Parser类型处理类型声明解析支持PHP Parser类型处理类型声明解析支持 引言现代PHP类型系统的演进 随着PHP语言的不断发展类型系统经历了从弱类型到强类型的重大变革。从PHP 7编译器静态分析代码生成zotero-style类型定义global.d.ts全局类型声明深度解析还在为Zotero插件开发中的类型错误烦恼吗一文带你彻底掌握zotero style的全局类型系统让你的开发效率提升200% 全局类型架构全景 zoter桌面应用知识管理科研上一篇BiSheng ReBAC 列表性能优化实战Cursor 分页 无限滚动改造全解析F027下一篇如何快速上手Laravel-api-generator5分钟搭建RESTful API的实战教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询