我一直在学习SML,事实证明这是一项艰巨的任务。我正在尝试创建一个函数,它接受一个整数列表,然后只返回该列表中的偶数。
这是我到目前为止所做的:
fun isEven [] = [] |
val evenList
if x mod 2 = 1 then //append to evenList
我非常依赖于我接下来应该做的事情。任何人都可以对此有所了解吗?
答案 0 :(得分:1)
在这个例子中(对于大多数列表处理问题),通常最容易考虑两种可能性:列表是空的,或者不是。当列表为空时,问题可能很难解决。当列表不为空时,您可以将列表解构为两部分:第一个元素(" head"),以及其余元素(" tail")。 / p>
在代码中,我们可以根据输入的内容编写许多不同版本的函数。下面是我在输入上的模式匹配和写两个不同的函数体,具体取决于输入是否为空。当它不为空时,列表的头部绑定到变量x
,尾部绑定到变量xs
:
fun f [] = (* ... empty case ... *)
| f (x :: xs) = (* ... non-empty case ... *)
在这个"惯用语"然后,您可以问:当列表非空时,如何解决递归问题?也就是说,是否可以将相同的函数应用于列表的尾部,并使用它来构建最终答案?
fun f [] = (* ... TODO: trivial when list is empty ... *)
| f (x :: xs) =
let
val foo = f xs
in
(* ... TODO: how to use `foo`? ... *)
end
此时,我会把剩下的留给你。尽量填补空白:foo
在您的问题中代表什么?你需要对head元素x
做什么?
答案 1 :(得分:0)
一个名为isEven
的函数听起来像一个谓词,而不是一个过滤器。
fun isEven n =
n mod 2 = 0
您可以将其称为evens
:
fun evens [] = ... (* base case *)
| evens (n::ns) = ... (* recursive case *)
现在你可以调用isEven
来确定n
的第一个n::ns
(至少有一个{1}},否则函数会匹配基本情况而不是递归情况)甚至是:
if isEven n then ... else ...
请注意,SML 中的 if-then-else 有 else 部分。
在任何一种情况下,您都希望继续在ns
上找到答案,但您只想在结果中加入n
,具体取决于isEven n
的值。您可以通过创建n
也是其成员的新列表在结果中包含某些内容。例如,一个函数将列表中的每个元素递增1:
fun incr [] = []
| incr (n::ns) = n+1 :: incr ns
除evens
外,您不想修改n
,n :: ...
部分是有条件的。