11

部分的に適用された演算子だけを使用して、「2で除算」や「1を減算」などの演算を渡すことができますか。「1を加算」は次のようになります。

List.map ((+) 1) [1..5];;  //equals [2..6]
// instead of having to write: List.map (fun x-> x+1) [1..5]

何が起こっているのかというと、最初の引数として1が(+)に適用され、2番目の引数としてリスト項目が適用されています。加算と乗算の場合、この引数の順序は重要ではありません。

すべての要素から1を引きたいとしましょう(これはおそらく初心者のよくある間違いです):

List.map ((-) 1) [1..5];;  //equals [0 .. -4], the opposite of what we wanted

最初の引数として(-)に1が適用されるため、の代わりに(list_item - 1)、を取得し(1 - list_item)ます。正の値を減算する代わりに負の値を加算するように書き直すことができます。

List.map ((+) -1) [1..5];;
List.map (fun x -> x-1) [1..5];; // this works too

Arc言語のように、プレースホルダーを表すのような((-) _ 1)、より表現力豊かな書き方を探しています。_これ1により、の2番目の引数に-なるため、List.mapでは。と評価されlist_item - 1ます。したがって、リストにマップdivide by 2する場合は、次のように記述できます。

List.map ((/) _ 2) [2;4;6] //not real syntax, but would equal [1;2;3] 
List.map (fun x -> x/2) [2;4;6] //real syntax equivalent of the above

これを行うことはできますか、それとも使用する必要があります(fun x -> x/2)か?プレースホルダー構文に最も近いのは、名前付き引数でラムダを使用することのようです。

4

3 に答える 3

16

次のようなフリップ関数を書くことができます。

let flip f x y = f y x

List.map (flip (-) 1) [2;4;6]

構文が間違っている可能性があります。F#はそれほど流暢ではありません。

于 2009-11-30T03:02:38.077 に答える
10

F#には「操作セクション」、Haskell、プレースホルダー引数(明らかにArc)はありません。別の回答で提案されているように「flip」コンビネータを使用して、引数の順序を逆にしてから、最初の(現在は2番目の)引数を部分的に適用できます。

しかし、私はただ使用します

fun x -> x / 2

あなたがコードゴルフをしているのでない限り、ここでさらに数人のキャラクターを剃ろうとしても何も買わないと思います。

于 2009-11-30T03:09:31.323 に答える
10

Logan Capaldoflipによって提案された-solutionは、演算子(ここ)を使用して記述することもできます。>.

let (>.) x f = (fun y -> f y x)
List.map (1 >. (-)) [2;4;6]

または、逆にオペランドを使用する場合は、次のようにします。

let (>.) f x = (fun y -> f y x)
List.map ((-) >. 1) [2;4;6]

編集:「プレースホルダーのように見える」演算子(ここ>-<)を使用すると、提案された構文に非常に近くなります。

List.map ((-) >-< 1) [2;4;6]

'_'は残念ながら(?)F#の有効な演算子記号ではありません。

于 2009-11-30T08:53:27.993 に答える