在我试图转换为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)
我想知道如何将 带有yield的seq {...}表达式转换为OCaml?我的第一个猜测是seq必须成为一个列表.
最简单的翻译(不是尾递归)是:
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
是不必要的潜在异常来源.并且有多余的括号.