Sml 为什么可以';我不能围绕addAll函数调用simplify吗?
我做这个作业是为了做家庭作业,我已经被困在这个问题上3个小时了。我刚刚给教授发了电子邮件,但还没有收到他们的回复,所以我决定也在这里问一下 我们被指派编写各种函数,例如以(14,2)的格式查找分数的gcd,其中14是分子,2是分母 我有gcd、simplify、add和times等函数,但我仍然坚持使用addAll addAll应该获取一个分数列表,这些分数被描述为坐标对,然后将它们相加并简化,然后以一个分数(分子、分母)的形式返回答案 目前,我的addAll函数将它们全部相加并返回正确格式的分数,但它并没有简化它。我已经编写了simplify函数,但是每当我尝试围绕addAll递归调用调用simplify时,就会出现错误 我目前的代码是:Sml 为什么可以';我不能围绕addAll函数调用simplify吗?,sml,Sml,我做这个作业是为了做家庭作业,我已经被困在这个问题上3个小时了。我刚刚给教授发了电子邮件,但还没有收到他们的回复,所以我决定也在这里问一下 我们被指派编写各种函数,例如以(14,2)的格式查找分数的gcd,其中14是分子,2是分母 我有gcd、simplify、add和times等函数,但我仍然坚持使用addAll addAll应该获取一个分数列表,这些分数被描述为坐标对,然后将它们相加并简化,然后以一个分数(分子、分母)的形式返回答案 目前,我的addAll函数将它们全部相加并返回正确格式的分
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;
趣味gcd(a、b)=
如果b=0,则a其他gcd(b,a模式b);
(a,b)=如果gcd(a,b)<2,那么(a,b)其他((a分区gcd(a,b)),(b分区gcd(a,b));
乐趣加(a,b)(c,d)=简化(a*d+c*b,b*d);
娱乐时间(a,b)(c,d)=简化((a*c),(b*d));
fun addAll L=如果L=[]那么[(0,1)]else如果tl L=nil那么L else addAll(
[
((#1(hdl))*(#2(hd(tll)))+(#1(hd(tll)))*(#2(hdl))、(#2(hdl))*(#2(hd(tll)))
]
@
(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=[]那么[(1,1)]else如果tl L=nil那么L else timesAll();*)
fun lessThan(a,b)(c,d)=如果((实a)/(实b))<((实c)/(实d)),则为真,否则为假;
我终于明白了
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)
这可以简化
但是:您已经实现了加法,因此无需再次执行。为了添加列表中的所有元素,您可以将其头部添加到其尾部所有元素的相加结果中。
添加一个基本案例,您就有了
fun addAll [] = (0, 1)
| addAll (x::xs) = add x (addAll xs);
(您甚至不需要这么多,但您可能还没有学习过foldl
和foldr
。如果已经学习过,请尝试将它们应用于此问题。)
您可以用同样的方式简化
timesAll
功能。请比“我遇到了错误”更具体一些。如果你对模式匹配更加熟悉,你会帮自己一个大忙的。谢谢你,我们甚至还没有学过模式匹配yet@JoshK您已经不知不觉地学会了模式匹配——您的所有其他函数都会这样做,但只在成对的情况下,而不是在列表上。