35

簡単な質問です。標準ライブラリ (または Jane Street の Core または Batteries) で定義されている OCaml に、Haskell の (.) 関数のような中置関数合成演算子があるかどうか疑問に思っています(f . g . h) x。あまり魅力的ではありませんf (g (h x)))

ありがとうございます。

4

6 に答える 6

30

flipここでの答えは:-)の場合と同じです。OCaml 標準ライブラリでは、関数合成は定義されていません。この場合、たまに恋しくなるのではなく、いつも恋しくなります。

OCaml Batteries Includedプロジェクトは-|、モジュール内の演算子を使用して、(指定した順序で) 関数合成を定義しBatStdます。lukstafi が指摘しているように (以下を参照)、この演算子は%Batteries の将来のリリースで変更されるようです。(ソースツリーでこれを確認しました。)

私の知る限り、Jane Street Coreプロジェクトは関数合成演算子を定義していません。composeモジュール内の関数を定義しFnます。

于 2013-05-19T16:52:35.547 に答える
16

演算子を含めるのはかなり簡単であることを追加したいだけです。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))
于 2013-10-06T23:03:52.790 に答える
14

Core にはFn.compose関数がありますが、中置演算子ではありません。また、通常の関数として実装され、実行時のオーバーヘッドがあります。

実際には、パイプ演算子を使用すると非常に便利です。コンパイラに直接実装されているため、実行時のオーバーヘッドはありません (4.00 以降)。詳細については、最適化されたパイプ オペレーターを参照してください。

Core では、パイプ演算子は '|>' として使用できます。したがって、式を次のように書き換えることができます。h x |> g |> f

于 2013-05-20T12:39:28.497 に答える
10

中置合成演算子の使用は推奨されないようです。(このディスカッションを参照してください)。

f @@ g @@ h xの代わりに書くことができますf (g (h x)))

于 2015-10-12T17:34:09.850 に答える
2

多分それはあなたを助けることができます。

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
于 2015-10-12T23:17:27.030 に答える