使用相互递归辅助函数的F#函数

使用相互递归辅助函数的F#函数,f#,F#,定义F#函数toc:Document→ 生成文档目录的ToC。例如,文档的前缀应带有编号副标题,如下所示: type Title = string type Document = Title * Element list and Element = Par of string | Sec of Document;; let s1 = ("Background", [Par "Bla"]) let s21 = ("Expressions", [Sec("Arithmet

定义F#函数
toc:Document→ 生成文档目录的ToC
。例如,文档的前缀应带有编号副标题,如下所示:

 type Title    = string
 type Document = Title * Element list
 and  Element  = Par of string | Sec of Document;;

 let s1   = ("Background", [Par "Bla"])
 let s21  = ("Expressions", [Sec("Arithmetical Expressions", [Par "Bla"]);
                             Sec("Boolean Expressions", [Par "Bla"])])
 let s222 = ("Switch statements", [Par "Bla"])
 let s223 = ("Repeat statements", [Par "Bla"])
 let s22  = ("Statements",[Sec("Basics", [Par "Bla"]) ; Sec s222; Sec s223])
 let s23  = ("Programs", [Par "Bla"])
 let s2   = ("The Programming Language", [Sec s21; Sec s22; Sec s23])
 let s3   = ("Tasks", [Sec("Frontend", [Par "Bla"]);
                       Sec("Backend", [Par "Bla"])])
 let doc  = ("Compiler project", [Par "Bla"; Sec s1; Sec s2; Sec s3]);;

你的问题似乎遗漏了不少东西。例如:您认为哪些相互递归的辅助函数有助于实现这一点

在我看来,这应该是一个简单的递归函数。基本逻辑可以是:

  • 对于每个元素,如果它是一个段落,忽略它,或者如果它是一个小节,则生成相应的TOC
  • 将新索引(每个小节一个,从1开始)附加到每个小节中的所有条目
  • [],title
    添加到此TOC的开头

  • 通过迭代序列表达式中的节,保留当前节的编号并生成具有当前节编号的所有标题,可以相对轻松地完成此操作

    [([], "Compiler project");
         ([1], "Background");
         ([2], "The Programming Language");
         ([2;1], "Expressions");
         ([2;1;1], "Arithmetical Expressions");
         ([2;1;2], "Boolean Expressions");
         ([2;2], "Statements");
         ([2;2;1], "Basics");
         ([2;2;2], "Switch statements");
         ([2;2;3], "Repeat statements");
         ([2;3], "Programs");
         ([3], "Tasks");
         ([3;1], "Frontend");
         ([3;2], "Backend")]
    

    你的问题是什么?到目前为止你试过什么?这是家庭作业吗?不是,到目前为止我们已经尝试了很多东西。我们正在考虑是否可以使用以前生成的函数来帮助我们实现这个函数。像这一个尝试尝试计算文档中的部分的数量:当List.IsEffess Es>>0(t,es)-> CurtSeS和CurtSeC(E:元素列表):It=匹配空d(t,es):int=匹配于E秒(t,es)::xs->1 + CurtSeSE+CurtScSxsPar t::XS->CurtScSx[]->0 noOfSecs doc和这一个用于打印每个部分的标题:让rec titlesInDoc(d:Document):Title list=在列表时将d与|(t,es)匹配。isEmpty es->[]|(t,es)->addToList es和addToList(e:元素列表):Title list=将e与| Sec(t,es)匹配::XS->T::AddiTeleAdTeleTistSXPART::AXTROLIST XS[[]-][TITLISDIONC(“编译器项目”,[PAR“BLA”;SEC S1;SEC S2;SEC S3])让Test= TimelDunoc DOCI只需要实现一个函数,使输出具有每个节的标题和节号。例如,重复陈述应具有第2节;2.3.
    // Given the current level (as a list of numbers) and a list of elements, 
    // generate a list of headings in the elements and prepend `idx` indices
    // to each heading that we generate
    let rec generateToc idx elems = seq {
    
      // We only care about nested sections, so this gets a list containing
      // just sections and we later add number to them using `Seq.indexed`
      let nested = elems |> Seq.choose (function 
        | Sec(title, elems) -> Some(title, elems) | _ -> None) 
    
      // For every nested section, we yield the title of the section and then
      // recursively call `generateToc` to get the nested section titles
      // (we append the current section number to `idx` when making the recursive call)
      for i, (title, elems) in Seq.indexed nested do
        yield List.rev (i+1::idx), title
        yield! generateToc (i+1::idx) elems }
    
    // To generate document TOC, we just yield the document title and
    // then call `generateToc` on the document elements
    let generateDocToc (title, elems) = seq {
      yield [], title
      yield! generateToc [] elems }
    
    generateDocToc  doc
    |> Seq.iter (printfn "%A")