4

OCamlに基づくいくつかのモジュールをF#に変換していますが、このようなものに遭遇しました

let [x; y; z] = map func1 ["a"; "b"; "c"]

where [x; y; z]は識別子 map func1 ["a"; "b"; "c"]のリストで、関数のリストを返します。

現在、リスト内の各値を個別に識別子にバインドしています。

let fList = map func1 ["a"; "b"; "c"]
let x = fList.[0]
let y = fList.[1]
let z = fList.[2]

識別子の使用は、2 番目の機能、つまり

func2 x y z 

リストを受け入れるように func2 を変更できることはわかっていますが、実際には func2 は各パラメーターの各関数と一緒に値を取得するため、さらに多くの作業が必要になります。すなわち

func2 (x g) (y h) (z i)

OCaml と同じくらい効率的にこれを行う方法を探しましたが、空っぽになりました。unmap、deconstruct を検索し、Listのメソッドを調べました

F# は値のリストを識別子のリストに直接マップできますか?

編集

私が変換しているコードは、独自のライブラリで map 関数を定義しています。

編集

@OnorioCatenacci実際に機能する例を作成するのに何分も費やすのではなく、例として書いたものにすぎません。実際のコードには著作権があるため、完全な開示なしにここで使用することはできません。私が言おうとしていたポイントは、識別子に定数値を割り当てていたのではなく、関数を識別子に割り当てていたということでした。map func1 ["a"; "b"; "c"]ハードコーディングされたものではなく、何らかの入力に基づいて必要に応じて関数が生成されていることを示すためだけに入力しました。実際のコードは論理回路シミュレータを構築し、返される関数は異なる論理回路です。コンビネータを考えてください。それはすべて、自動化された定理証明器の一部です。Tomas と Daniel は質問を理解し、私が実際のコードで検証した正しい答えを出しました。

つまりfunc1 "a"、パラメータを使用して関数を返します"a"map func1 ['a", "b", "c"]関数のリストを返します。関数はF# ではファースト クラスであるため、値として返すことができます。

4

2 に答える 2

7

マップをリストに適用してから、パターンマッチングを使用して、要素をF#の識別子にバインドできます。構文は、作成したサンプルとまったく同じです。

let [x; y; z] = List.map func1 ["a"; "b"; "c"] 

この例の唯一の問題は、F#コンパイラが結果が長さ3のリストになることを静的に検証できないため、「この式に不完全なパターンが一致する」という警告が表示されることです。この例では、実際には発生しませんが、たとえば、map最初の要素を破棄するように誤って再定義すると、コードが破損します。

これは単なる警告であるため、無視してかまいませんが、回避したい場合matchは、予期しない場合にカスタム例外を使用してスローする必要があります。

match List.map func1 ["a"; "b"; "c"] with
| [x; y; z] ->
   // Continue here if the pattern matching does not fail
   func2 (x g) (y h) (z i) 
| _ -> invalidOp "Pattern matching failed"
于 2012-05-09T15:47:40.643 に答える
6

Tomas が言及している「不完全なパターン一致」の警告を回避したい場合は、固定長のタプルを使用して、独自のmap関数を定義できます。

module Tuple3 =
  let map f (a, b, c) = (f a, f b, f c)

let x, y, z = Tuple3.map func1 ("a", "b", "c")
于 2012-05-09T16:07:48.347 に答える