Functional programming 需要帮助在OCaml中打印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

我是新来的,所以如果我的帖子不好,我会提前道歉。 我试图构建一个列表,其中包含以下相互递归的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) = 
    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。