为什么我不能围绕我的 addAll 函数调用简化?

  • 本文关键字:函数调用 addAll 不能 sml
  • 更新时间 :
  • 英文 :


我做这项作业是为了做家庭作业,我已经被这个问题困扰了大约3个小时。我刚给教授发了电子邮件,但还没有收到他们的回复,所以我决定也在这里询问。

我们被指派编写各种函数,例如以(14,2(的格式找到分数的gcd,其中14是分子,2是分母。

我已经完成了函数gcd、simple、add和times,但我一直在使用addAll。

addAll应该取一个被描述为坐标对的分数列表,将它们相加并简化,然后将答案返回为一个这样格式的分数(分子、分母(。

目前,我的addAll函数将它们全部相加,并返回正确格式的分数,但它并没有简化它。我已经编写了simple函数,但每当我试图在addAll递归调用周围调用simple时,我都会出错。

我当前的代码是:

fun addAll L = if L = [] then [(0, 1)] else if tl L = nil then L else addAll(    
[
( ((#1 (hd L)) * (#2 (hd (tl L)))) + (#1 (hd (tl L))) * (#2 (hd L)), (#2 (hd L))*(#2 (hd (tl L))) )
]
@
(tl (tl L))
);
(*
a = (#1 (hd L))
b = (#2 (hd L))
c = (#1 (hd (tl L)))
d = (#2 (hd (tl L)))
*)

我试图通过这样做来解决问题:

fun addAll L = if L = [] then [(0, 1)] else if tl L = nil then L else simplify(addAll(    
[
( ((#1 (hd L)) * (#2 (hd (tl L)))) + (#1 (hd (tl L))) * (#2 (hd L)), (#2 (hd L))*(#2 (hd (tl L))) )
]
@
(tl (tl L))
));
(*
a = (#1 (hd L))
b = (#2 (hd L))
c = (#1 (hd (tl L)))
d = (#2 (hd (tl L)))
*)

但是我犯了错误。

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

谢谢。

此外,如果有帮助的话,我会附上我在sml中运行的全部代码。。。

这是我所有的任务代码:

fun gcd (a, b) =
if b = 0 then a else gcd(b, a mod b);
fun simplify (a, b) = if gcd(a, b) < 2 then (a, b) else ((a div gcd(a, b)), (b div gcd(a, b)));
fun add (a,b) (c,d) = simplify((a*d + c*b), b*d);
fun times (a,b) (c,d) = simplify( (a*c), (b*d) );
fun addAll L = if L = [] then [(0, 1)] else if tl L = nil then L else addAll(    
[
( ((#1 (hd L)) * (#2 (hd (tl L)))) + (#1 (hd (tl L))) * (#2 (hd L)), (#2 (hd L))*(#2 (hd (tl L))) )
]
@
(tl (tl L))
);
(*
a = (#1 (hd L))
b = (#2 (hd L))
c = (#1 (hd (tl L)))
d = (#2 (hd (tl L)))
*)

(*fun timesAll L = if L = [] then [(1, 1)] else if tl L = nil then L else timesAll();*)

fun lessThan (a, b) (c, d) = if ((real a) / (real b)) < ((real c) / (real d)) then true else false;

我终于解决了!

fun addAll L = if L = [] then (0, 1) else if tl L = nil then ((#1 (hd L)) , (#2 (hd L))) else simplify(addAll(    
[
( ((#1 (hd L)) * (#2 (hd (tl L)))) + (#1 (hd (tl L))) * (#2 (hd L)), (#2 (hd L))*(#2 (hd (tl L))) )
]
@
(tl (tl L))
));


(*
a = (#1 (hd L))
b = (#2 (hd L))
c = (#1 (hd (tl L)))
d = (#2 (hd (tl L)))
*)

使用许多选择器的代码–如hdtl#1…–很难阅读
这是您的模式匹配功能,它在视觉上更容易:

fun addAll [] = [(0,1)]
| addAll [x] = [x]
| addAll ((a0, b0)::(a1, b1)::xs) = addAll ((a0 * b1 + a1 * b0, b0 * b1) :: xs)

(我还用x :: xs替换了构建体[x] @ xs。(

问题是,这个函数应该产生一对,而不是一个对列表:

fun addAll [] = (0,1)
| addAll [x] = x
| addAll ((a0, b0)::(a1, b1)::xs) = addAll ((a0 * b1 + a1 * b0, b0 * b1) :: xs)

这可以是CCD_ 6编辑的

但是:您已经实现了加法,所以不必再做一次
为了添加列表中的所有元素,您可以将其头部添加到其尾部所有元素相加的结果中
添加一个基本案例,您就有了

fun addAll [] = (0, 1)
| addAll (x::xs) =  add x (addAll xs);

(你甚至不需要那么多,但你可能还没有了解foldlfoldr。如果你了解了,试着将它们应用于这个问题。(

您可以用同样的方式简化timesAll函数。

最新更新