Functional programming 需要帮助在OCaml中打印hofstadter女性序列中的前N个数字吗
我是新来的,所以如果我的帖子不好,我会提前道歉。 我试图构建一个列表,其中包含以下相互递归的hofstadter序列的前n个数字:Functional programming 需要帮助在OCaml中打印hofstadter女性序列中的前N个数字吗,functional-programming,ocaml,Functional Programming,Ocaml,我是新来的,所以如果我的帖子不好,我会提前道歉。 我试图构建一个列表,其中包含以下相互递归的hofstadter序列的前n个数字: F(0) = 1 M(0) = 0 F(n) = n - M(F(n-1)), n > 0 M(n) = n - F(M(n-1)), n > 0 我正试图用OCaml来做这件事,这对我来说是一种新的语言。在为这个问题奋斗了一整天之后,我想到了这个: open Printf let list = [];; let rec female (n: int
F(0) = 1
M(0) = 0
F(n) = n - M(F(n-1)), n > 0
M(n) = n - F(M(n-1)), n > 0
我正试图用OCaml来做这件事,这对我来说是一种新的语言。在为这个问题奋斗了一整天之后,我想到了这个:
open Printf
let list = [];;
let rec female (n: int) =
if n == 0 then 1::list
else let x = n - male(female(n-1)) in x::list
and male (n:int) =
if n == 0 then 0::list
else let x = n - female(male(n-1)) in x::list
in female 4;; (** test number*)
let () = List.iter (printf "%d ") list
但它在第8行不断产生一个类型错误
此模式匹配int类型的值
但需要一个与int list类型的值匹配的模式
有人能帮我理解为什么我会犯这个错误吗?函数式编程并不是我的强项。您有这样一个子表达式:
male (female (n-1))
由此我们可以得出结论,男性
的参数类型与女性
的结果类型相同。但就在上面,我们看到female
在一种情况下返回此值:
1 :: list
这是一个整数列表
因此我们知道male
的第一个参数应该是一个int列表。但是,当您实际定义male
时,您有:
and male (n:int) =
编译器告诉您,male
的第一个参数有两个相互冲突的要求。在一个地方它是一个整数列表,在另一个地方(男性的定义)你说它是一个整数
您需要有一个一致的计划来确定
男性
和女性
的参数应该是什么。多亏了杰夫的评论,我终于找到了答案。以下是我的解决方案:
let rec female (n: int) =
match n with
| 0 -> 1
| _ -> n - male(female(n-1))
and male (n:int) =
match n with
| 0 -> 0
| _ -> n - female(male(n-1));;
let rec l i =
if i < 10 then female i :: l (i+1)
else []
in
List.iter (fun item -> print_int item; print_newline ()) (l 0)
let rec female(n:int)=
匹配
| 0 -> 1
|->n-男性(女性(n-1))
及男(n:int)=
匹配
| 0 -> 0
|_un-女性(男性(n-1));;
让我记录一下=
如果i<10,则女性i::l(i+1)
其他[]
在里面
List.iter(趣味项目->打印整型项目;打印换行())(l0)
打印hofstadter女性序列的前10个数字:6 5 5 4 3 2 1谢谢!所以看起来我有一个设计缺陷,我怎么能去修复它呢?
male n
应该返回什么?它是否应该返回您定义的M
序列中的第n个数字?如果是这样,您根本不需要处理列表。你可以只处理数字。或者它应该返回M
序列的第一个n
编号的列表吗?这有点难(它涉及更多的FP战术)。这是一个正确的问题。因此,假设男性和女性都返回序列的第n个元素,那么在逻辑上正确吗?为每个0-n元素调用一个单独的循环,并以这种方式构建列表?您可能会发现,利用OCaml的模式匹配语法,您的代码更具表现力(从而更容易推理)<代码>让rec female n=将n与0->匹配代码>vs.使用if/else。