sml - 是否可以在标准 ML 中支持更高种类的类型?
问题描述
我在这篇文章中读到 ML 方言不允许非地面类型的类型变量。例如最后一条语句是不可表示的:
-- Haskell code
type Ground = Int
type FirstOrder a = Maybe a
type SecondOrder c = c Int -- ML do not allow :c
OCaml 仅在模块级别支持更高种类。关于 OCaml 的哪些功能与更高级的类型机会发生冲突,有一些解释(此处和作者的评论)。
如果我理解正确,主要问题在于以下事实:
- OCaml 不遵循类型定义的“新鲜度”限制:构造
type
可以定义别名(类型将保持不变)和新的新鲜类型 - 类型别名定义可以隐藏
AFAIK,标准 ML 对类型定义和别名有不同的结构:type
别名和datatype
新类型的引入。
不幸的是,我不太了解 SML —— 是否可以导出类型别名并隐藏其定义?有人可以告诉我是否还有其他 SML 功能仍然不能很好地适应更高种类的类型的机会吗?
仿函数可能会出现一些问题——有人能这么好心地展示一个代码示例吗?我已经多次听说过这样的案例,但仍然没有找到完整的例子。
解决方案
是的,SML 可以通过函子表达等价的更高种类的类型,也可以将它们抽象化。无用的例子:
functor F (type 'a t) :> sig type 'a u end =
struct
type 'a u = ('a t) t
end
但是,与 OCaml 不同的是,SML(官方)没有高阶仿函数,因此根据标准,您只能以这种方式表示二阶类型构造函数。
FWIW,OCaml 可能对类型别名和生成类型使用相同的关键字(在 SML 中type
vs datatype
),但它们在语法上仍然可以通过它们的右侧进行区分。所以这与 SML 没有真正的区别。在这两种语言中,出现在签名中的抽象可以实现为类型别名或生成类型。因此,Leo 所暗示的类型推断问题同样存在于两者中。Haskell 可以摆脱这个问题,因为它在类型抽象方面没有相同的表现力(即,没有模块的“密封”运算符)。
推荐阅读
- blockchain - 无法在本地以太坊区块链中添加对等点
- python - 如何优化抓取动态加载的网站?
- oracle - sql中隐式游标的行数
- angular - 如何在 mat tooltip angular 中添加静态文本和动态变量?
- google-bigquery - Google Data Studio - 使 COUNT_DISTINCT 作用于整个数据而不是饼图中的特定类别
- android - Firebase 数据库规则关于
- winapi - WTSVirtualChannelOpen在C#中调用错误调用,getLastWin32Error()返回错误调用6,windows的invalid_invalid_handle
- sql - 如何生成序列号以在 Sql Server 行中不断变化
- c++ - 无法在 C++ 中将击键写入记事本
- python - 如何在模板中请求 GET 参数以获取文件列表?(Django Zip 文件下载问题)