请看Crates。
这里有一个快速的 sn-p 描述你想要完成的关键。我相信这个 sn-p 很有价值,因为它有助于教会我们如何通过使用数学语言正式推理使用 F# 和其他 ML 类型系统。换句话说,它不仅向您展示了如何工作,而且还教会了您为什么它起作用的深层原理。
这里的问题是我们已经达到了 F# 中可直接表达的基本限制。因此,模拟全称量化的技巧是避免直接传递函数,而是将类型参数隐藏起来,这样调用者就不能将其固定为一个特定的值,但是怎么可能做到这一点?
回想一下,F# 提供了对 .NET 对象系统的访问。如果我们创建自己的类(在面向对象的意义上)并在其上放置一个通用方法呢?我们可以创建我们可以传递的实例,从而携带我们的函数(以所述方法的形式)?
// Encoding the function signature...
// val id<'a> : 'a -> 'a
// ...in terms of an interface with a single generic method
type UniversalId = abstract member Eval<'a> : 'a -> 'a
现在我们可以创建一个实现,我们可以在不固定类型参数的情况下传递它:
// Here's the boilerplate I warned you about.
// We're implementing the "UniversalId" interface
// by providing the only reasonable implementation.
// Note how 'a isn't visible in the type of id -
// now it can't be locked down against our will!
let id : UniversalId =
{ new UniversalId with
member __.Eval<'a> (x : 'a) : 'a = x
}
现在我们有一种方法可以模拟一个普遍量化的函数。我们可以将id 作为一个值传递,并且在任何时候我们选择一个类型'a 来传递给它,就像我们传递任何值级参数一样。
存在量化
There exists a type x, such that…
existential 是一个静态类型未知的值,要么是因为我们有意隐藏了已知的东西,要么是因为类型确实是在运行时选择的,例如由于反思。但是,在运行时,我们可以检查存在性以找到其中的类型和值。
如果我们不知道存在量化类型中的具体类型,我们如何安全地对其执行操作?好吧,我们可以应用任何本身可以处理任何类型值的函数——即我们可以应用一个普遍量化的函数!
换句话说,存在性可以用可用于操作它们的普遍性来描述。
这种技术非常有用,它被用于数据类型通用编程库 TypeShape,它允许您废弃您的样板 .NET 反射代码,以及用于“打包存在数据类型”的 MBrace 和 FsPickler。请参阅 Erik Tsarpalis 的 slides on TypeShape 了解更多关于“在 .NET 中编码 安全 存在解包”和在 .NET 中编码 rank-2 类型。
像 TypeShape 这样的反射辅助库直观地也应该涵盖大部分(如果不是全部)用例:依赖注入需要在底层实现服务定位,因此 TypeShape 可以被认为是用于构建依赖关系的“原始组合库”注入。请参阅以Arbitrary Type Shapes 开头的幻灯片:特别注意 Code Lens 数据类型:
type Lens<'T,'F> =
{
Get : 'T -> 'F
Set : 'T -> 'F -> 'T
}
最后,如果您想了解更多想法,请阅读 Don Stewart 的博士论文,Dynamic Extension of Typed Functional Languages。
我们提出了一种解决静态扩展问题的方法
类型擦除的类型化功能语言。提出的解决方案保留
静态检查的好处,包括类型安全、积极优化和组件的本机代码编译,同时允许
程序在运行时的可扩展性。
我们的方法是基于一个静态的动态扩展框架
类型化设置,结合动态链接,运行时类型检查,
一流的模块和代码热交换。 我们展示了这个框架
足以在任何情况下允许广泛的动态扩展功能
具有类型擦除语义的静态类型函数式语言。
独特的是,我们使用完整的编译时类型系统来执行运行时
动态组件的类型检查,并强调使用native
代码扩展以确保静态类型的性能优势
保留在动态环境中。我们还开发了以下概念
完全动态的软件架构,其中静态核心最少且
所有代码都是可热插拔的。该方法的好处包括可热插拔
通过嵌入式领域特定的代码和复杂的应用程序扩展
语言。
以下是 Don 列出的一些粗粒度设计模式,供未来工程师遵循:
- 第 3.6.3 节:专业化模拟器方法。
- 演示如何将程序专业化技术应用于聚合物化学的蒙特卡罗模拟。这种方法演示了如何“注入”专门的代码来解决所谓的“窥孔优化”。
以及帮助构建“可扩展性之塔”的一般图表: