3

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
        }

そのseq{...} 式をyield 'sでOCamlに変換する方法について疑問に思っていますか?私の最初の推測は、seqがリストになる必要があるということです。

4

3 に答える 3

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

テール再帰バージョンは次のとおりです。

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)

開始している F# コードには、多くの要望が残されていることに注意してください。と の呼び出しはList.headList.tail代わりにパターン マッチングをより簡単に使用できる場合、不必要な例外の潜在的な原因となります。そして余分な括弧があります。

于 2013-01-20T19:44:07.353 に答える
3

seqこれは遅延リスト、つまり、一度にではなく必要なときに末尾が計算されるリストだと思います。OCaml で最も近いものは、camlp4 で利用できる拡張機能であるストリーム パーサーかもしれません。OCaml マニュアルの言語拡張セクションに記載されています。

fun () -> exprリストの末尾を表すためにを使用して、独自の明示的な遅延リスト機能を作成することもできます。

リストがかなり小さい場合は、提案どおりに通常のリストに変換することもできます。

于 2013-01-20T19:42:57.197 に答える
2

私はLazyList.fromバッテリーを見てみます:http://ocaml-batteries-team.github.com/batteries-included/hdoc2/BatLazyList.html

ただし、ソリューションほど便利ではないと思います。

于 2013-01-20T19:55:32.577 に答える