簡単な質問です。 Haskellの(。)関数のように、標準ライブラリ(またはJane StreetのCoreまたはBatteries)で定義されたOCamlに中置関数合成演算子があるかどうか疑問に思っています。これにより、_(f . g . h) x
_あまり魅力的でないf (g (h x)))
の代わりに。
皆さん、ありがとう。
ここでの答えはflip
の場合と同じです:-)。関数の合成はOCaml標準ライブラリで定義されていません。この場合、たまに見逃すものではなく、いつも見逃しているものです。
OCaml Batteries Included プロジェクトは、 BatStd
モジュールで演算子-|
を使用して、関数の合成を(指定した順序で)定義します。 lukstafiが指摘しているように(以下を参照)、この演算子は、バッテリーの将来のリリースで%
に変更されるようです。 (私は彼らのソースツリーでこれを確認しました。)
私が見る限り、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))
_
有る Fn.compose
Coreの関数ですが、中置演算子ではありません。また、通常の関数として実装され、実行時のオーバーヘッドがあります。
実際には、パイプ演算子を使用すると非常に便利です。コンパイラに直接実装されているため、実行時のオーバーヘッドはありません(4.00以降)。詳細については、 最適化されたパイプ演算子 を参照してください。
パイプ演算子は、Coreでは「|>」として使用できます。したがって、式を次のように書き直すことができます。h x |> g |> f
中置合成演算子の使用は推奨されていないようです。 ( この議論 を参照)。
f (g (h x)))
の代わりにf @@ g @@ h x
を書くことができます。
Containers (Ocamlのさらに別のstdlib置換)では、関数合成演算子は%
と呼ばれ、 CCFun モジュールにあります。
open Containers
open Fun
let is_zero n = (n = 0)
let nonzeros = List.filter (not % is_zero) [0;1;2;3;0]
多分それはあなたを助けることができます。
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