関数への引数を持つ演算子を渡すF#
-
08-07-2019 - |
質問
<!> quot; 2 <!> quotで除算するなどの操作を渡すことができますか?または<!> quot; subtract 1 <!> quot;部分的に適用された演算子のみを使用します。ここで、<!> quot; add 1 <!> quot;次のようになります。
List.map ((+) 1) [1..5];; //equals [2..6]
// instead of having to write: List.map (fun x-> x+1) [1..5]
1番目の引数として(+)に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
((-) _ 1)
のような、より表現力のある記述方法を探しています。ここで、_
はArc言語のようにプレースホルダーを示します。これにより、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)
を使用する必要がありますか?プレースホルダー構文に最も近いのは、名前付き引数でラムダを使用することです。
解決
次のようなフリップ関数を書くことができます:
let flip f x y = f y x
List.map (flip (-) 1) [2;4;6]
構文が間違っている可能性があります。F#にそれほど堪能ではありません。
他のヒント
F#には「操作セクション」はなく、Haskellにも、プレースホルダー引数(明らかにla Arc)もありません。別の回答で提案されているように、「フリップ」コンビネータを使用して引数の順序を逆にし、最初の(現在2番目の)引数を部分的に適用できます。
しかし、私はただ使用します
fun x -> x / 2
コードゴルフをプレイしていない限り、ここでさらに数人のキャラクターを剃ろうとしても何も買わないと思う。
Logan Capaldo が提案する flip
-solutionは、演算子(ここでは&gt;。
):
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]
編集:「プレースホルダのように見える」演算子を使用します。 (ここでは&gt;-&lt;
)を使用すると、推奨構文に非常に近いものになります。
List.map ((-) >-< 1) [2;4;6]
'_'は残念ながら(?)ではなく a F#の有効な演算子記号。