【问题标题】:Return a list of even numbers in SML返回 SML 中的偶数列表
【发布时间】:2017-12-14 21:23:38
【问题描述】:

我一直在学习 SML,这已被证明是一项艰巨的任务。我正在尝试创建一个接收整数列表的函数,然后只返回该列表中的偶数。

这是我目前所拥有的:

fun isEven [] = [] |
    val evenList            
    if x mod 2 = 1 then //append to evenList

我非常坚持接下来应该做的事情。任何人都可以对此有所了解吗?

【问题讨论】:

  • List.filter (fn i => i mod 2 = 0)

标签: sml


【解决方案1】:

在这个例子中(对于大多数列表处理问题),通常从考虑两种可能性开始是最容易的:要么列表为空,要么不为空。当列表为空时,问题可能很容易解决。当列表不为空时,您可以将列表解构为两部分:第一个元素(“头”)和其余元素(“尾”)。

在代码中,我们可以根据输入的样子编写许多不同版本的函数。下面我对输入进行模式匹配并编写两个不同的函数体,具体取决于输入是否为空。不为空时,链表头部绑定变量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 做什么?

【讨论】:

    【解决方案2】:

    名为isEven 的函数听起来像是谓词,而不是过滤器。

    fun isEven n =
        n mod 2 = 0
    

    你可以叫它evens

    fun evens [] = ... (* base case *)
      | evens (n::ns) = ... (* recursive case *)
    

    现在您可以调用isEven 来确定@​​987654327@ 的第一个n(至少有一个,否则该函数将匹配基本情况而不是递归情况)是否为偶数:

    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的情况,你不想修改nn :: ...部分是有条件的。

    【讨论】:

      猜你喜欢
      • 2020-10-28
      • 2016-02-01
      • 1970-01-01
      • 2016-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多