我正在制作一个返回斐波那契数列表的函数;但是我收到了错误
7.25-7.37: mismatch on application: expression type
int list
does not match function's argument type
int list list
because type
int
does not unify with
int list
这是我的代码:
fun fibl [] = [0]
| fibl [0] = [0]
| fibl [1] = [1]
| fibl n = fibl[n]
| fibl [n] =
let
val f = fn () => fibl [n - 1] + fibl [n - 2]
in
(f ())::[n]
end;
解释器说错误发生在lambda中,但我理解它的方式;写fibl [n]
表示它会检查一个列表,然后当您稍后使用n
时,您正在使用它包含的值,因此我不应该使用fibl
来调用{{1}}一个int列表列表,但只是一个int列表,所以我不知道这里出了什么问题,任何人都有线索?
答案 0 :(得分:3)
您的代码存在多个问题。
从这一行开始
| fibl n = fibl [n]
您正在匹配前两行中的整数列表。因此,您的函数必须将这样的列表作为输入。但是,在上面这一行中,您将获取整数列表n
,并在另一个列表n
内打包fibl [n]
递归调用您的函数。
但请注意,此匹配在修复时会生成无限循环!
另一个问题是你的最后一场比赛是多余的,因为上面的比赛会抓住所有输入,导致你的最后一场比赛更新。
您在上一场比赛中也有一些错误。请注意,您的函数将其结果作为单例列表返回。在函数f
中,您尝试添加fibl
函数的结果(即int列表),这是可能的。
在这里你要么必须从列表中“拉出”号码,要么做一些完全不同的事情。
由于您正在尝试生成斐波纳契数列表,我建议您执行完全不同的操作,因为您当前的方法仅生成两个斐波纳契数的列表。 我建议你从一个天真的解决方案开始;具有将生成第n个斐波那契数的函数,然后通过反复应用此函数生成列表。
根据要求,以下是一些如何天真地做到这一点的例子。
首先我们定义一个能产生第n个斐波纳契数的函数。
fun fib 0 = 0
| fib 1 = 1
| fib n = fib (n-1) + fib (n-2)
然后可以通过数字列表轻松映射此函数,生成特定斐波那契数字的列表
- val fibLst = map fib [0,1,2,3,4,5,6,7,8];
val fibLst = [0,1,1,2,3,5,8,13,21] : int list
但是我们也可以创建一个函数,它将生成一个列表0 ... n,然后将fib函数应用于该列表。
fun genFib n = List.tabulate (n, fib);
或没有List.tabulate函数
fun genFib1 n =
let
fun loop 0 acc = fib 0 :: acc
| loop m acc = loop (m-1) (fib m :: acc)
in
loop (n-1) []
end
显然,fib函数可以更好地实现,我们的列表生成函数可以利用下一个斐波那契数的创建方式。您会注意到以下函数在生成包含前40个斐波纳契数的列表时要快得多。
fun genFib2 n =
let
fun loop 0 _ _ acc = rev acc
| loop m f_1 f_2 acc = loop (m-1) f_2 (f_1 + f_2) (f_2 :: acc)
in
loop (n-1) 0 1 [0]
end
以上在SML中有一个整数大小的问题(你可以生成第44个斐波纳契数,但不能生成第45个)。因此我们可以扩展fib函数以使用任意精度整数IntInf,以及上面的想法
fun fibInf n : IntInf.int =
let
fun loop 0 f_1 _ = f_1
| loop m f_1 f_2 = loop (m-1) f_2 (f_1 + f_2)
in
loop n 0 1
end
现在它既“快速”又可能产生前100个斐波纳契数或更多
fun genFibInf n = List.tabulate (n, fibInf);
- genFibInf 1000;
val it = [0,1,1,2,3,5,8,13,21,34,55,89,...] : IntInf.int list
- List.nth(it, 700);
val it =
8747081495575284620397841301757132734236724096769738107423043259252750#
: IntInf.int
答案 1 :(得分:1)
另一个生成Fibonacci数列表的函数,直到 n -th:
fun fibs 0 = [0]
| fibs 1 = [1, 0]
| fibs n =
case fibs (n - 1) of
(n1::n2::ns) => (n1+n2::n1::n2::ns)
| _ => raise Fail "Not possible"
(修复从(1,1,......)或(1,2,......)开始的斐波纳契数定义的基本情况。