如何避免结构和签名中的SML数据类型重复?

shh*_*you 5 module sml algebraic-data-types

给出A带有数据类型的签名t,比方说

signature A = sig
    datatype t = T of int | S of string
end
Run Code Online (Sandbox Code Playgroud)

是否有可能提供一个没有t重复的实现(结构)?例如,在以下签名中,t重复定义.它适用于小型数据类型,但对于较大的数据类型则有点笨拙.

structure AImpl : A = struct
    datatype t = T of int | S of string
end
Run Code Online (Sandbox Code Playgroud)

我的目的只是提供一个接口,以便人们可以知道所有的声明.但我不希望每个实现都重复数据类型定义.

虽然签名和结构似乎都可以包含来自另一个结构的数据类型,但是通过单独检查签名,人们就无法知道数据类型声明.例如:

structure AData = struct
    datatype t = T of int | S of string
end

signature A = sig
    datatype t = datatype AData.t
end

structure a : A = struct
    open AData
end
Run Code Online (Sandbox Code Playgroud)

当然,这种方法,虽然不是很有满足感,是可以接受的,如果我把两者ADataA在同一个.sig文件中.

tck*_*tck 1

不,这是不可能的,因为签名匹配规则在 sml 中是如何工作的。

当您在签名中引入某些非抽象类型时,具有此签名的每个结构都必须提供相同的类型绑定。原因是 sml 中的签名主要用于隐藏结构细节。

例如,您可以使用抽象类型向结构用户隐藏数据类型详细信息:

signature A = 
sig
  type t
end


structure AImpl :> A = 
struct
   datatype t = T of int | S of string
end
Run Code Online (Sandbox Code Playgroud)

或者您可以只公开一种类型构造函数:

signature A = 
sig
  type t
  val T : int -> t
end


structure AImpl :> A = 
struct
   datatype t = T of int | S of string
end

val test = AImpl.T 12;
Run Code Online (Sandbox Code Playgroud)