Nickel 语言:是一种配置语言,也是函数式编程语言。函数式编程定义不明确,从能模糊传递函数作为参数到基于 lambda 演算的静态类型、纯且不可变语言都算。随机问开发者,总会提到代数数据类型(ADTs)和模式匹配,它们是类型化函数式语言的核心。
- 核心语言特性:let 绑定、头等函数、记录(JSON 对象)、静态类型(默认动态类型,静态类型注解可进行静态类型检查)、合约(类似类型,运行时评估)。
- 生命周期:编写、评估、序列化(通常为 JSON、YAML 或 TOML),设定每个原生数据结构应能简单直接序列化到 JSON 的准则,有枚举类型(类似 C 或 JavaScript 的标签,序列化后为字符串)和
match
(类似 C 或 JavaScript 的switch
)。
ADTs 在配置语言中的情况:
- 序列化难题:希望值能直接序列化为 JSON 数据模型,但对于简单 ADT 的序列化方式难以提前确定,导致考虑使用(非标记)联合类型,其优势是不做序列化选择,而是作为新类型(和合约)对已有可表示值进行分类。
- 联合类型之路:联合类型是接受不同替代的类型,用
\/
类型组合符表示,如{literal: Number \/ String}
,在 TypeScript 中可用于模拟 ADTs,但 Nickel 中联合和交集合约实现困难,限制了用联合类型表示 ADTs 的想法。
- ADTs 的用途:在编写更多 Nickel 代码后,意识到在库函数中缺少 ADTs,如
enum Option<T> { Some(T), None }
和Result<T,E> = { Ok(T), Error(E) }
,有多个使用 ADTs 使库更友好的示例,如std.string.find
函数可返回适当的 ADT 以改善接口,在合约定义中使用Result<T,E>
可使自定义合约接口更简单自然。 设计:
- 结构与名义:传统 ADTs 是名义形式,Nickel 目前的类型系统是结构的,更适合处理任意 JSON 样数据,对于 ADTs 来说结构形式更合适,OCaml 有结构 ADTs(多态变体)。
- 语法:C 风格枚举是 ADTs 的特殊情况,ADTs 用枚举加参数表示,如
'Some "hello"
,'Ok
不是函数应用而是 ADT 构造函数应用,限制 ADTs 为单个参数,可用记录模拟多个参数,ADTs 还带有模式匹配。 - 类型检查:结构 ADTs 的类型检查与名义 ADTs 不同,引入子类型可解决类型不匹配问题,但子类型有缺陷,Nickel 依赖行多态,可对枚举类型的子序列进行抽象,如
forall a. [| 'Ok Number; a |]
,通过行多态可推断'Ok 42
的类型。
- 结论:由于配置语言设计的特殊性,Nickel 最近才引入 ADTs,探索联合类型无果后,确定了结构版本的 ADTs,它是语言的自然扩展,已在编写更清晰简洁代码和改善库接口方面发挥作用。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。