簡単な質問です。標準ライブラリ (または Jane Street の Core または Batteries) で定義されている OCaml に、Haskell の (.) 関数のような中置関数合成演算子があるかどうか疑問に思っています(f . g . h) x
。あまり魅力的ではありませんf (g (h x)))
。
ありがとうございます。
簡単な質問です。標準ライブラリ (または Jane Street の Core または Batteries) で定義されている OCaml に、Haskell の (.) 関数のような中置関数合成演算子があるかどうか疑問に思っています(f . g . h) x
。あまり魅力的ではありませんf (g (h x)))
。
ありがとうございます。
flip
ここでの答えは:-)の場合と同じです。OCaml 標準ライブラリでは、関数合成は定義されていません。この場合、たまに恋しくなるのではなく、いつも恋しくなります。
OCaml Batteries Includedプロジェクトは-|
、モジュール内の演算子を使用して、(指定した順序で) 関数合成を定義しBatStd
ます。lukstafi が指摘しているように (以下を参照)、この演算子は%
Batteries の将来のリリースで変更されるようです。(ソースツリーでこれを確認しました。)
私の知る限り、Jane Street Coreプロジェクトは関数合成演算子を定義していません。compose
モジュール内の関数を定義しFn
ます。
演算子を含めるのはかなり簡単であることを追加したいだけです。F# では、次のように単純に定義されています。
let (<<) f g x = f(g(x));;
これには型シグネチャがあります:val ( << ) : f:('a -> 'b) -> g:('c -> 'a) -> x:'c -> 'b
必要なことを正確に行う...
(f << g << h) x = f(g(h(x))
必要がない場合は、バッテリープロジェクトは必要ありません
ご想像のとおり、演算子が反対のことを行うため、このように見える理由があることを付け加えたいと思い<<
ます。>>
let (>>) f g x = g(f(x));;
(f >> g >> h) x = h(g(f(x))
Core にはFn.compose
関数がありますが、中置演算子ではありません。また、通常の関数として実装され、実行時のオーバーヘッドがあります。
実際には、パイプ演算子を使用すると非常に便利です。コンパイラに直接実装されているため、実行時のオーバーヘッドはありません (4.00 以降)。詳細については、最適化されたパイプ オペレーターを参照してください。
Core では、パイプ演算子は '|>' として使用できます。したがって、式を次のように書き換えることができます。h x |> g |> f
中置合成演算子の使用は推奨されないようです。(このディスカッションを参照してください)。
f @@ g @@ h x
の代わりに書くことができますf (g (h x)))
。
多分それはあなたを助けることができます。
let identite f = f
let (>>) = List.fold_right identite
テスト:
# let f=fun x-> x+1 and
g=fun x-> x*2 and
h=fun x-> x+3;;
# [f;g;h] >> 2;;
- : int = 11