我想复制一个函数-
for i in range(10):
for j in range(10):
do something with i, j
在SML中有一种简单的方法吗?
答案 0 :(得分:2)
您当然可以这样做,但是您应该考虑是否真的只想do something with i, j
并丢弃结果。那是内在的命令性逻辑,不是真正的惯用标准ML。
但是,如果这确实是您想要的,那么有几种方法。这是当务之急:
let val i = ref 0
in while !i < 10 do
( let val j = ref 0
in while !j < 10 do
( do something with i, j
; j := !j + 1
)
end
; i := !i + 1
)
end
这是一个更加惯用的语言:
let val range0To9 = List.tabulate (10, fn i => i)
in List.app range0To9 (fn i => List.app range0To9 (fn j => do something with i, j))
end
答案 1 :(得分:0)
这取决于您要做什么。
是否要为每个(i,j)产生副作用,例如打印一些东西?
fun appulate (n, f) =
let fun go i = if i < n then (f i; go (i+1)) else ()
in go 0 end
val show = Int.toString
val _ = appulate (10, fn i =>
appulate (10, fn j =>
print ("(" ^ show i ^ ", " ^ show j ^ ")\n")))
还是要产生结果值?这个值是列表还是其他?
作为一个具体示例,Pythagorean triplets in SML上有一个问答。它询问如何将使用列表推导的Haskell代码片段移植到不具有列表推导功能的Standard ML。您可以使用Python 3做一个非常相似的案例。它的range()
函数不会产生 list ,而是可以迭代的对象。
SML的List.tabulate
实际上会产生一个列表,如果您随后要立即丢弃或过滤该列表,则会降低其内存效率。我链接的“问题与解答”讨论了在三个整数范围的笛卡尔乘积(即找到毕达哥拉斯三重奏的笛卡尔积)上对做某事的特定情况的可读性和效率。
也许您举一个具体的例子来做某事,您会得到更好的答复。 :-)
可以通过具体示例随意修改您的问题。