如何在 ATS 中的给定列表上编写循环?
How to write a loop over a given list in ATS?
假设我有一个列表xs。如何在 ATS 中编写以下循环样式:
foreach x in xs do process(x)
您可以使用旧的 DIY 风格(也可以是经典的 ATS 风格),也就是说,使用尾递归函数。这是一个例子:
extern
fun
process (x: int): void
fun
loop {n:int} (xs: list(int, n)): void =
case+ xs of
| list_nil () => ()
| list_cons (x, xs1) => let
val () = process (x)
in
loop (xs1)
end
// end of [loop]
您可以运行完整代码online
如果 ATSLIB 等库中提供的 none 组合器或模板函数适合您的情况,我认为这种方法更可取。
基于组合器的解决方案(对于 list0
值):
(xs).foreach()(lam x => process(x))
在 ATS 中,foreach
重载了许多执行某种形式的序列遍历的函数。
如果需要每个元素的位置还有iforeach
:
(xs).iforeach()(lam (i, x) => process(i, x))
这是一个需要避免的糟糕解决方案!
函数式编程的初学者经常使用 list_get_at
函数(重载符号 []
)进行列表遍历。例如,看到代码或多或少地执行以下行的操作是很常见的:
(length(xs)).foreach()(lam i => process(xs[i])) // O(n^2)-time
这是非常低效的。在循环中调用 list_get_at
几乎总是一个坏主意!
假设我有一个列表xs。如何在 ATS 中编写以下循环样式:
foreach x in xs do process(x)
您可以使用旧的 DIY 风格(也可以是经典的 ATS 风格),也就是说,使用尾递归函数。这是一个例子:
extern
fun
process (x: int): void
fun
loop {n:int} (xs: list(int, n)): void =
case+ xs of
| list_nil () => ()
| list_cons (x, xs1) => let
val () = process (x)
in
loop (xs1)
end
// end of [loop]
您可以运行完整代码online
如果 ATSLIB 等库中提供的 none 组合器或模板函数适合您的情况,我认为这种方法更可取。
基于组合器的解决方案(对于 list0
值):
(xs).foreach()(lam x => process(x))
在 ATS 中,foreach
重载了许多执行某种形式的序列遍历的函数。
如果需要每个元素的位置还有iforeach
:
(xs).iforeach()(lam (i, x) => process(i, x))
这是一个需要避免的糟糕解决方案!
函数式编程的初学者经常使用 list_get_at
函数(重载符号 []
)进行列表遍历。例如,看到代码或多或少地执行以下行的操作是很常见的:
(length(xs)).foreach()(lam i => process(xs[i])) // O(n^2)-time
这是非常低效的。在循环中调用 list_get_at
几乎总是一个坏主意!