在 SML 中创建重复函数
Create a repeat function in SML
我正在创建一个名为 repeat
的函数,它接受两个 int 列表 lst1
和 lst2
。假设lst2
只有非负整数,根据第二个列表lst2
指示的数字重复第一个列表lst1
中的整数。如果两个列表都是空的,return 一个空列表。您可能需要一个本地函数。
示例:
repeat ([1,2,3], [4,0,3])
-> [1,1,1,1,3,3,3]
我在开始使用这个功能时遇到了一些麻烦。我应该在 xs 后面放什么?
fun repeat(lst1, lst2) =
case lst1 of
[] => []
| x::xs' => [] (* what should I put here *)
与任何递归问题一样,您的基本情况是什么?我会说在这种情况下它的两个列表都是空的,它给你一个空列表。
fun repeat([], []) = []
如果一个是空的而另一个不是怎么办?那是一个失败。如果发生这种情况,让我们定义一个可以抛出的异常。
exception MismatchedArguments;
fun repeat([], []) = []
| repeat([], _) = raise MismatchedArguments
| repeat(_, []) = raise MismatchedArguments
现在真正的问题是我们剩下的时间都在做什么。幸运的是,SML 可以轻松地对两个列表进行模式匹配并提取它们的第一个元素。
exception MismatchedArguments;
fun repeat([], []) = []
| repeat([], _) = raise MismatchedArguments
| repeat(_, []) = raise MismatchedArguments
| repeat(x::xs, y::ys) = ...
此时,我们需要一个递归函数来将列表中的一个元素重复一定次数。与整体功能一样,这里我们看到递归的两个标志:至少 一个 基本“退出”条件,以及我们通过更新 [=15 向基本条件收敛的更新步骤=] 到 n - 1
.
exception MismatchedArguments;
fun repeat([], []) = []
| repeat([], _) = raise MismatchedArguments
| repeat(_, []) = raise MismatchedArguments
| repeat(x::xs, y::ys) =
let
fun repeat'(_, 0) = []
| repeat'(x, n) = x :: repeat'(x, n - 1)
in
...
end
现在,我们只需要将它们放在一起,将 x
和 y
提供给 repeat'
,然后将其与再次调用 repeat
的结果连接起来xs
和 ys
。通过这样做,我们会收敛到 repeat([], [])
或 的基本情况,我们可能会收敛到引发 MismatchedArguments
异常的不匹配场景。
exception MismatchedArguments;
fun repeat([], []) = []
| repeat([], _) = raise MismatchedArguments
| repeat(_, []) = raise MismatchedArguments
| repeat(x::xs, y::ys) =
let
fun repeat'(_, 0) = []
| repeat'(x, n) = x :: repeat'(x, n - 1)
in
repeat'(x, y) @ repeat(xs, ys)
end
现在 repeat([1, 2, 3], [4, 0, 3])
将产生 [1, 1, 1, 1, 3, 3, 3]
。
我正在创建一个名为 repeat
的函数,它接受两个 int 列表 lst1
和 lst2
。假设lst2
只有非负整数,根据第二个列表lst2
指示的数字重复第一个列表lst1
中的整数。如果两个列表都是空的,return 一个空列表。您可能需要一个本地函数。
示例:
repeat ([1,2,3], [4,0,3])
-> [1,1,1,1,3,3,3]
我在开始使用这个功能时遇到了一些麻烦。我应该在 xs 后面放什么?
fun repeat(lst1, lst2) =
case lst1 of
[] => []
| x::xs' => [] (* what should I put here *)
与任何递归问题一样,您的基本情况是什么?我会说在这种情况下它的两个列表都是空的,它给你一个空列表。
fun repeat([], []) = []
如果一个是空的而另一个不是怎么办?那是一个失败。如果发生这种情况,让我们定义一个可以抛出的异常。
exception MismatchedArguments;
fun repeat([], []) = []
| repeat([], _) = raise MismatchedArguments
| repeat(_, []) = raise MismatchedArguments
现在真正的问题是我们剩下的时间都在做什么。幸运的是,SML 可以轻松地对两个列表进行模式匹配并提取它们的第一个元素。
exception MismatchedArguments;
fun repeat([], []) = []
| repeat([], _) = raise MismatchedArguments
| repeat(_, []) = raise MismatchedArguments
| repeat(x::xs, y::ys) = ...
此时,我们需要一个递归函数来将列表中的一个元素重复一定次数。与整体功能一样,这里我们看到递归的两个标志:至少 一个 基本“退出”条件,以及我们通过更新 [=15 向基本条件收敛的更新步骤=] 到 n - 1
.
exception MismatchedArguments;
fun repeat([], []) = []
| repeat([], _) = raise MismatchedArguments
| repeat(_, []) = raise MismatchedArguments
| repeat(x::xs, y::ys) =
let
fun repeat'(_, 0) = []
| repeat'(x, n) = x :: repeat'(x, n - 1)
in
...
end
现在,我们只需要将它们放在一起,将 x
和 y
提供给 repeat'
,然后将其与再次调用 repeat
的结果连接起来xs
和 ys
。通过这样做,我们会收敛到 repeat([], [])
或 的基本情况,我们可能会收敛到引发 MismatchedArguments
异常的不匹配场景。
exception MismatchedArguments;
fun repeat([], []) = []
| repeat([], _) = raise MismatchedArguments
| repeat(_, []) = raise MismatchedArguments
| repeat(x::xs, y::ys) =
let
fun repeat'(_, 0) = []
| repeat'(x, n) = x :: repeat'(x, n - 1)
in
repeat'(x, y) @ repeat(xs, ys)
end
现在 repeat([1, 2, 3], [4, 0, 3])
将产生 [1, 1, 1, 1, 3, 3, 3]
。