Functional programming 从sml中的整数对列表返回偶数列表
我有一个问题:“给定一个整数对列表,编写一个函数以在sml中返回该列表中的偶数列表” 这就是我到目前为止所取得的成就Functional programming 从sml中的整数对列表返回偶数列表,functional-programming,sml,smlnj,Functional Programming,Sml,Smlnj,我有一个问题:“给定一个整数对列表,编写一个函数以在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
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);
valx=[(6,2)、(3,4)、(5,6)、(7,8)、(9,10)];
乐趣无穷(num:int)=
如果num mod 2=0,则num else为0;
有趣的数字(列表:(int*int)列表)=
如果列表为空,则为[]else
如果isEven(#1(hd列表))0
那么如果isEven(#2(hd list))0
然后#1(高清列表)::#1(高清列表)::偶数(tl列表)
其他[]
否则如果isEven(#2(hd列表))0
然后#1(hd列表)::偶数(tl列表)
else[];
偶数(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列表…
和(x,y)::当输入列表为非空(包含至少一个元素,即(x,y))时成对的
模式匹配
。同时,它将这一元素解构为其各个部分,x
和y
。因此,在第二个函数体中,您可以表示isEven x
和isEven y
由于总共有四种组合决定了x
和y
是否为偶数,因此很容易就会产生类似复杂的if-then-else。为此,我可以做两件事中的一件:
对上递归调用偶数
):
我看到两个明显的问题 如果第一个数字和第二个数字都是偶数,则为偶数
#1 (hd list) :: #1 (hd list) :: evenNumbers(tl list)
#1 (hd list) :: evenNumbers(tl list)
它将第一个数字相加两次并忽略第二个数字
如果第一个数字是奇数,第二个数字是偶数,你就可以
#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”是一个非常奇怪的答案),那么它会更有用
现在,evernumbers
可以“仅仅”实现为其他更通用功能的组合
fun isEven x = x mod 2 = 0