将F#seq表达式转换为OCaml

ane*_*eal 3 f# ocaml

在我试图转换为OCaml的F#代码中,我遇到了以下问题:

    let rec parseList lst off =
        seq {
            if List.isEmpty lst then ()
            else
                match parse off <| List.head lst with
                | (Unmatched, _) as y -> yield y
                | (y, z) -> yield (y, z)
                            yield! parseList (List.tail lst) z
        }
Run Code Online (Sandbox Code Playgroud)

我想知道如何将 带有yieldseq {...}表达式转换为OCaml?我的第一个猜测是seq必须成为一个列表.

Jon*_*rop 5

最简单的翻译(不是尾递归)是:

let rec parseList lst off =
  match lst with
  | [] -> []
  | x::xs ->
      match parse off x with
      | Unmatched, _ as y -> [y]
      | y, z -> (y, z)::parseList xs z
Run Code Online (Sandbox Code Playgroud)

尾递归版是:

let parseList lst off =
  let rec loop xs off = function
    | [] -> xs
    | y::ys ->
        match parse off y with
        | Unmatched, _ as x -> x::xs
        | _, z as x -> loop (x::xs) z ys in
  List.rev (loop [] off lst)
Run Code Online (Sandbox Code Playgroud)

请注意,您开始使用的F#代码有很多不足之处.当您可以更轻松地使用模式匹配时,调用List.head并且List.tail是不必要的潜在异常来源.并且有多余的括号.

  • 这似乎是最简单的方法.由于F#创建了一个seq,然后继续立即将该seq转换为列表,我猜想使用LazyList或Stream模块没有多大优势. (2认同)
  • "*请注意,您开始使用的F#代码有很多不足之处.*"仅此+1. (2认同)