SML:改变结构中 INT 的值
SML : Changing value of INT in a structure
我有一个小问题。
我进行了计算,但我所有的 ID 都不再相互关联(因为在计算过程中进行了一些删除)。不幸的是,为了使我的结果有效,我需要这个命令...:/
因此,为了简化任务,我制作了一个外部函数,它将 "rename" 所有 ID,但我不知道如何执行此操作。
这是我得到的函数:
fun setId (W {id, ...}) =
let
in
print( "[" ^ Int.toString (id) ^ "]");
print( "[" ^ Int.toString (!nextId) ^ "]\n");
Ref.incr nextId
end
(对于游荡的人app
只是一个自制的函数,对列表的每个元素执行相同的计算,但这并不重要。)
当我执行这段代码时,我在输出中获得:
[0][0]
[1][1]
[2][2]
[3][3]
[4][4]
[5][5]
[6][6]
[7][7]
[8][8]
[9][9]
[10][10]
[11][11]
[12][12]
[13][13]
[14][14]
[15][15]
[16][16]
[17][17]
[18][18]
[19][19]
[20][20]
[21][21]
[22][22]
[39][23]
[40][24]
[41][25]
[42][26]
[43][27]
[44][28]
[45][29]
[46][30]
[47][31]
[48][32]
[49][33]
[50][34]
[51][35]
[52][36]
[53][37]
如您所见,存在一个大问题 [23] [39]
列表中没有以下数字。 :/
基本上,我希望函数setId
能够修改节点的ID。但我不知道如何:/
这里是数据类型 Node
以供理解:
datatype node =
W of {
id : int
, predId : int option
, creationDepcy : Dependency.depcy
, nominalDepcies : Dependency.depcy list ref
, pattern : Termstore.store
, propositions : Propstore.pstore
, nominals : Propstore.pstore
, diamonds : Termstore.store
, boxes : Termstore.store
, disjunctions : Termstore.store
, nglstore : Termstore.store
, lazyProps : Lazystore.store
, lazyNoms : Lazynomstore.store
, lazyBoxes : Lazyboxstore.store
, blockedDiamonds : (Term.index * int) list ref
, branchPoints : int list ref
}
在此先感谢您的帮助!
此致。
由于 id
是键入的 int
,因此无法修改。如果将其更改为 int ref
则可以修改它,但您还必须更改访问器以取消引用 ref
.
另一种解决方案是创建一个从旧 ID 映射到新 ID 的数组,并使用该数组进行展示,但这似乎更加复杂。
由于 ints
是不可变的 -- 您可以获取节点列表并将其替换为新的节点列表:
fun newID (W(x), i) =
W({
id = i
, predId = #predId x
, creationDepcy = #creationDepcy x
, nominalDepcies = #nominalDepcies x
, pattern = #pattern x
, propositions = #propositions x
, nominals = #nominals x
, diamonds = #diamonds x
, boxes = #boxes x
, disjunctions = #disjunctions x
, nglstore = #nglstore x
, lazyProps = #lazyProps x
, lazyNoms = #lazyNoms x
, lazyBoxes = #lazyBoxes x
, blockedDiamonds = #blockedDiamonds x
, branchPoints = #branchPoints x
});
fun imap _ [] _ = []
| imap f (x::xs) i = f(x,i):: (imap f xs (i+1));
(imap
代表"increment map")
然后如果xs
是一个节点列表函数调用
imap newID xs 0
将生成一个新的节点列表,其中 id
字段以 0
开头的连续整数
免责声明:当然,我没有在您的设置中尝试此操作,因为我创建了一个包含 id
字段的记录数据类型并成功使用了此方法。显然,由于所有的复制,这不是您想要做的很多事情,但是如果它在您代码中的一个特定点,它应该没问题。
大部分等同于 John 的解决方案,这里是如何在不使用引用的情况下更新节点列表,而是使用折叠。函数setId
同理
fun setIds firstId ws =
#1 (foldr (fn (w,(ws',nextId)) => (setId w nextId::ws', nextId+1)) ([],firstId) ws)
运行 setIds 1 [w1, w2, w3, ...]
会产生 [w1', w2', w3', ...]
.
我有一个小问题。
我进行了计算,但我所有的 ID 都不再相互关联(因为在计算过程中进行了一些删除)。不幸的是,为了使我的结果有效,我需要这个命令...:/
因此,为了简化任务,我制作了一个外部函数,它将 "rename" 所有 ID,但我不知道如何执行此操作。
这是我得到的函数:
fun setId (W {id, ...}) =
let
in
print( "[" ^ Int.toString (id) ^ "]");
print( "[" ^ Int.toString (!nextId) ^ "]\n");
Ref.incr nextId
end
(对于游荡的人app
只是一个自制的函数,对列表的每个元素执行相同的计算,但这并不重要。)
当我执行这段代码时,我在输出中获得:
[0][0]
[1][1]
[2][2]
[3][3]
[4][4]
[5][5]
[6][6]
[7][7]
[8][8]
[9][9]
[10][10]
[11][11]
[12][12]
[13][13]
[14][14]
[15][15]
[16][16]
[17][17]
[18][18]
[19][19]
[20][20]
[21][21]
[22][22]
[39][23]
[40][24]
[41][25]
[42][26]
[43][27]
[44][28]
[45][29]
[46][30]
[47][31]
[48][32]
[49][33]
[50][34]
[51][35]
[52][36]
[53][37]
如您所见,存在一个大问题 [23] [39]
列表中没有以下数字。 :/
基本上,我希望函数setId
能够修改节点的ID。但我不知道如何:/
这里是数据类型 Node
以供理解:
datatype node =
W of {
id : int
, predId : int option
, creationDepcy : Dependency.depcy
, nominalDepcies : Dependency.depcy list ref
, pattern : Termstore.store
, propositions : Propstore.pstore
, nominals : Propstore.pstore
, diamonds : Termstore.store
, boxes : Termstore.store
, disjunctions : Termstore.store
, nglstore : Termstore.store
, lazyProps : Lazystore.store
, lazyNoms : Lazynomstore.store
, lazyBoxes : Lazyboxstore.store
, blockedDiamonds : (Term.index * int) list ref
, branchPoints : int list ref
}
在此先感谢您的帮助!
此致。
由于 id
是键入的 int
,因此无法修改。如果将其更改为 int ref
则可以修改它,但您还必须更改访问器以取消引用 ref
.
另一种解决方案是创建一个从旧 ID 映射到新 ID 的数组,并使用该数组进行展示,但这似乎更加复杂。
由于 ints
是不可变的 -- 您可以获取节点列表并将其替换为新的节点列表:
fun newID (W(x), i) =
W({
id = i
, predId = #predId x
, creationDepcy = #creationDepcy x
, nominalDepcies = #nominalDepcies x
, pattern = #pattern x
, propositions = #propositions x
, nominals = #nominals x
, diamonds = #diamonds x
, boxes = #boxes x
, disjunctions = #disjunctions x
, nglstore = #nglstore x
, lazyProps = #lazyProps x
, lazyNoms = #lazyNoms x
, lazyBoxes = #lazyBoxes x
, blockedDiamonds = #blockedDiamonds x
, branchPoints = #branchPoints x
});
fun imap _ [] _ = []
| imap f (x::xs) i = f(x,i):: (imap f xs (i+1));
(imap
代表"increment map")
然后如果xs
是一个节点列表函数调用
imap newID xs 0
将生成一个新的节点列表,其中 id
字段以 0
免责声明:当然,我没有在您的设置中尝试此操作,因为我创建了一个包含 id
字段的记录数据类型并成功使用了此方法。显然,由于所有的复制,这不是您想要做的很多事情,但是如果它在您代码中的一个特定点,它应该没问题。
大部分等同于 John 的解决方案,这里是如何在不使用引用的情况下更新节点列表,而是使用折叠。函数setId
同理
fun setIds firstId ws =
#1 (foldr (fn (w,(ws',nextId)) => (setId w nextId::ws', nextId+1)) ([],firstId) ws)
运行 setIds 1 [w1, w2, w3, ...]
会产生 [w1', w2', w3', ...]
.