我做这项作业是为了做家庭作业,我已经被这个问题困扰了大约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)))
*)
使用许多选择器的代码–如hd
、tl
、#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);
(你甚至不需要那么多,但你可能还没有了解foldl
和foldr
。如果你了解了,试着将它们应用于这个问题。(
您可以用同样的方式简化timesAll
函数。