标准ML中的自引用记录类型

时间:2018-11-30 17:22:11

标签: types ml

我会创建一个记录类型声明,例如

type 'a cx = { foo : string, handler : 'a cx -> 'a cx }

但此代码无法编译。

我也尝试过“相互递归类型同义词声明”

type 'a cx = { foo : string, handler : 'a hnd }
and 'a hnd = 'a cx -> 'a cx;

没有成功。

在Haskell中,应该是

data Cx a = MkCx { foo :: String, handler :: Cx a -> Cx a }

如何在SML中实现?

更新

可以使用递归数据类型

datatype 'a cx = MkCx of string * ('a hnd)
and 'a hnd = MkHnd of 'a cx -> 'a cx;

但这很丑陋,并且没有无序访问的好的记录语法。

3 个答案:

答案 0 :(得分:2)

最接近您的尝试是:

datatype 'a cx = CX of { foo : string, handler : 'a hnd }
withtype 'a hnd = 'a cx -> 'a cx

但是,这需要模式匹配才能访问记录。定义访问器功能可能会更方便。

答案 1 :(得分:0)

我最终将单独的类型打包到单个模块中,即

type 'a cx = { foo : string };
type 'a hnd = 'a cx -> 'a cx
signature CX = sig
    type t
    val cx : t cx
    val handler : t hnd
end

答案 2 :(得分:0)

在SML / NJ中,使用单个构造函数构造代数数据类型对我来说是可行的,而无需定义多个类型:

datatype 'a cx = CX of { foo : string, handler : 'a cx -> 'a cx }

type不起作用,因为它仅定义了一个别名(例如C中的typedef),该别名不能递归。