返回SML中的偶数列表
我一直在学习SML,这已经证明是一项相当艰巨的任务。我试图创建一个函数,它接受一个整数列表,然后只返回该列表中的偶数 以下是我到目前为止的情况:返回SML中的偶数列表,sml,Sml,我一直在学习SML,这已经证明是一项相当艰巨的任务。我试图创建一个函数,它接受一个整数列表,然后只返回该列表中的偶数 以下是我到目前为止的情况: fun isEven [] = [] | val evenList if x mod 2 = 1 then //append to evenList 我对下一步该做的事感到非常困惑。有人能解释一下吗?在本例中(以及对于大多数列表处理问题),通常最容易从考虑两种可能性开始:列表是空的,或者不是空的。当列表为空时,
fun isEven [] = [] |
val evenList
if x mod 2 = 1 then //append to evenList
我对下一步该做的事感到非常困惑。有人能解释一下吗?在本例中(以及对于大多数列表处理问题),通常最容易从考虑两种可能性开始:列表是空的,或者不是空的。当列表为空时,问题可能很难解决。当列表不为空时,可以将列表分解为两部分:第一个元素(“head”),其余元素(“tail”)
在代码中,我们可以根据输入的外观编写许多不同版本的函数。下面我将对输入进行模式匹配,并根据输入是否为空编写两个不同的函数体。当它不为空时,列表的头部绑定到变量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
?一个名为isEven
的函数听起来像一个谓词,而不是一个过滤器
fun isEven n =
n mod 2 = 0
你可以称之为evens:
fun evens [] = ... (* base case *)
| evens (n::ns) = ... (* recursive case *)
现在,您可以调用isEven
,以确定n::ns
的第一个n
(至少有一个,否则函数将匹配基本情况而不是递归情况)是否为偶数:
注意,SML中的if-then-else必须有一个else部分
在这两种情况下,您都希望在ns
上继续查找evens,但您只希望根据isEven n
的值在结果中包含n
。您可以通过创建一个新列表,在该列表中n
也是一个成员,从而在结果中包含一些内容。例如,将列表中的每个元素递增1的函数:
fun incr [] = []
| incr (n::ns) = n+1 :: incr ns
除了在evens
的情况下,您不想修改n
,并且n:…
部分是有条件的。List.filter(fn i=>i mod 2=0)
fun incr [] = []
| incr (n::ns) = n+1 :: incr ns