我正在尝试将现有的int库扩展到名为" bigint"的新库。我将数据类型bigint的类型保留为int list。基本上,我想要一个函数(让我们称之为getbigint)接受任何int并将其每个数字存储在int list的单独单元格中,然后返回此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;*)
给出错误。
答案 0 :(得分:1)
签名不执行任何操作。它描述了一个结构对外界的看法。将其视为规范。与之匹配的结构必须提供签名中元素的实现。请注意,运行代码时会出现以下错误:
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)。