Return sml 中整数对列表中的偶数列表

Return a list of even numbers from a list of integer pairs in sml

我有以下问题“给定整数对列表,将函数写入 return sml 中该列表中的偶数列表”。

这是我到目前为止所取得的成就

val x = [(6, 2), (3, 4), (5, 6), (7, 8), (9, 10)];

fun isEven(num : int) = 
    if num mod 2 = 0 then num else 0;

fun evenNumbers(list : (int * int) list) = 
    if null list then [] else 
    if isEven(#1 (hd list)) <> 0
    then if isEven(#2 (hd list)) <> 0
         then #1 (hd list) :: #1 (hd list) :: evenNumbers(tl list)
         else []
    else if isEven(#2 (hd list)) <> 0
         then #1 (hd list) :: evenNumbers(tl list)
         else [];

evenNumbers(x);

结果应该是这样的[6,2,4,6,8,10]

如有任何帮助,我们将不胜感激。

所以运行你当前的代码,

- evenNumbers [(6, 2), (3, 4), (5, 6), (7, 8), (9, 10)];
val it = [6,6,3,5,7,9] : int list

表明您没有捕捉到所有偶数,而是捕捉到了一些奇数。

函数 isEven 听起来很像你想要这样的类型 int -> bool:

fun isEven n =
    n mod 2 = 0

我不想解决您当前解决方案的逻辑错误,而是想提出一种语法上更简单的方法,即使用模式匹配和更少的显式类型注释。这种解决方案的一个基础可能如下所示:

fun evenNumbers [] = ...
  | evenNumbers ((x,y)::pairs) = ...

使用模式匹配是 if-then-else 的替代方法:[] 模式等效于 if null list ...,而 (x,y)::pairs 模式在输入列表非空时匹配(包含至少一个元素,即 (x,y)。同时,它将这个元素解构为 xy 部分。所以在第二个函数体中你可以表达 isEven xisEven y.

由于 xy 是否偶数一共有四种组合,这很容易导致类似复杂的 if-then-else 嵌套。为此,我可能会做以下两件事之一:

  1. 用例(并在 pairs 上递归调用 evenNumbers):

    fun evenNumbers [] = ...
      | evenNumbers ((x,y)::pairs) =
          case (isEven x, isEven y) of
               ... => ...
             | ... => ...
    
  2. 将对列表展平为整数列表,然后filter它:

    fun flatten [] = ...
      | flatten ((x,y)::pairs) = ...
    
    val evenNumbers pairs = ...
    

我看到两个明显的问题。

如果第一个和第二个数字都是偶数,就可以

#1 (hd list) :: #1 (hd list) :: evenNumbers(tl list)

将第一个数字相加两次并忽略第二个。

如果第一个数字是奇数,第二个数字是偶数,那么你就是

#1 (hd list) :: evenNumbers(tl list)

它会添加您知道的奇数并忽略您知道的偶数。

使用选择器和条件进行编程会很快变得复杂(如您所见)。

有了模式匹配,你可以这样写

fun evenNumbers [] = []
  | evenNumber ((x,y)::xys) = ...

并降低使用错误选择器的风险。

不过这样还是逻辑复杂,还有更好的办法

考虑从数字列表中过滤出奇数而不是对的更简单的问题。
如果将输入转换为这样的列表,则只需解决那个更简单的问题(并且很有可能您已经在之前的练习中解决了非常相似的问题)。

练习:实现这个转换。它的类型将是 ('a * 'a) list -> 'a list.

另外,如果你的 isEven 产生真值(如果你问某人,“36 是偶数吗?”,“36”是一个非常奇怪的答案)。

fun isEven x = x mod 2 = 0

现在,evenNumbers 可以“仅”作为其他更通用的函数的组合来实现。