如何在 sml 中定义新签名
How to define new signature in sml
我正在尝试将现有的 int 库扩展到一个名为 "bigint" 的新库。我将数据类型 bigint 的类型保留为 int 列表。基本上,我想要一个函数(我们称之为 getbigint),它接受任何 int 并将其每个数字存储在一个单独的 int 列表单元格中,然后 return 这个 int 列表。所以如果我输入:
getbigint 9
它应该给我:
val it =[9]:bigint
我怎样才能做到这一点?目前,我假设此函数的输入仅为单个数字 int。这是我到目前为止所做的:
signature BigInt =
sig
type bigint = int list
val getbigint: int -> bigint
end;
structure struct_bigint : BigInt =
struct
fun getbigint (i:int) =
let
val h = [i]:bigint
in h
end
end
(*val j = getbigint 9;*)
出现错误。
签名不执行任何操作。它描述了一个结构在外界看来是什么样的。将其视为规范。匹配它的结构必须提供签名中元素的实现。请注意,当您 运行 您的代码时,您会收到以下错误:
Error: unmatched type specification: bigint
SML 检测到您的签名中有与结构中相应实现不匹配的内容。
最小的修复方法是添加行
type bigint = int list
在结构定义前执行fun getbigint
。这将允许行
val j = struct_bigint.getbigint 9;
上班。但是——
这行看起来有点傻
type bigint = int list
两次——一次在签名中,一次在结构中。而且,在某些方面,它 是 愚蠢的。
实现细节并不真正属于签名。在 签名 中使用 type bigint
并在 结构 中使用 int list
实现更有意义.这将允许您以后改变对实现的想法(比如您想要使用数组而不是列表),这样使用该结构的代码完全不受影响。类似于:
signature BIGINT =
sig
type bigint
val getbigint: int -> bigint
end
structure BigInt : BIGINT =
struct
type bigint = int list
fun getbigint (i:int): bigint = [i];
end;
我清理了你对 getbigint
的实现,因为其中的 let
绑定似乎有点毫无意义,并为签名(全部大写)和结构(驼峰)的名称选择了更惯用的名称首字母大写的案例。
最后,请注意 getbigint 9
无法开箱即用。您可以执行以下三项操作之一:
1) 显式使用限定名称:BigInt.getbigint 9
2) 使用行 val getbigint = BigInt.getbigint
赋予名称 getbigint
在当前范围内的预期含义
3) 使用行 open BigInt
将结构的定义移动到顶层,之后 getbigint 9
将按预期工作。
当我开始使用 SML 编程时,我常常打开很多结构(Char
、`List 等)。如果你不加考虑地这样做,迟早你会 运行 进入错误,打开结构会引入名称冲突。出于这个原因,我现在几乎总是使用方法 1) 或 2)。
我正在尝试将现有的 int 库扩展到一个名为 "bigint" 的新库。我将数据类型 bigint 的类型保留为 int 列表。基本上,我想要一个函数(我们称之为 getbigint),它接受任何 int 并将其每个数字存储在一个单独的 int 列表单元格中,然后 return 这个 int 列表。所以如果我输入:
getbigint 9
它应该给我:
val it =[9]:bigint
我怎样才能做到这一点?目前,我假设此函数的输入仅为单个数字 int。这是我到目前为止所做的:
signature BigInt =
sig
type bigint = int list
val getbigint: int -> bigint
end;
structure struct_bigint : BigInt =
struct
fun getbigint (i:int) =
let
val h = [i]:bigint
in h
end
end
(*val j = getbigint 9;*)
出现错误。
签名不执行任何操作。它描述了一个结构在外界看来是什么样的。将其视为规范。匹配它的结构必须提供签名中元素的实现。请注意,当您 运行 您的代码时,您会收到以下错误:
Error: unmatched type specification: bigint
SML 检测到您的签名中有与结构中相应实现不匹配的内容。
最小的修复方法是添加行
type bigint = int list
在结构定义前执行fun getbigint
。这将允许行
val j = struct_bigint.getbigint 9;
上班。但是——
这行看起来有点傻type bigint = int list
两次——一次在签名中,一次在结构中。而且,在某些方面,它 是 愚蠢的。
实现细节并不真正属于签名。在 签名 中使用 type bigint
并在 结构 中使用 int list
实现更有意义.这将允许您以后改变对实现的想法(比如您想要使用数组而不是列表),这样使用该结构的代码完全不受影响。类似于:
signature BIGINT =
sig
type bigint
val getbigint: int -> bigint
end
structure BigInt : BIGINT =
struct
type bigint = int list
fun getbigint (i:int): bigint = [i];
end;
我清理了你对 getbigint
的实现,因为其中的 let
绑定似乎有点毫无意义,并为签名(全部大写)和结构(驼峰)的名称选择了更惯用的名称首字母大写的案例。
最后,请注意 getbigint 9
无法开箱即用。您可以执行以下三项操作之一:
1) 显式使用限定名称:BigInt.getbigint 9
2) 使用行 val getbigint = BigInt.getbigint
赋予名称 getbigint
在当前范围内的预期含义
3) 使用行 open BigInt
将结构的定义移动到顶层,之后 getbigint 9
将按预期工作。
当我开始使用 SML 编程时,我常常打开很多结构(Char
、`List 等)。如果你不加考虑地这样做,迟早你会 运行 进入错误,打开结构会引入名称冲突。出于这个原因,我现在几乎总是使用方法 1) 或 2)。