web-dev-qa-db-ja.com

OCamlに中置関数合成演算子はありますか?

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

皆さん、ありがとう。

25
tfboy

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

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

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

25

演算子を含めるのはかなり簡単で、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))
_
10
Electric Coffee

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

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

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

9
Stas

中置合成演算子の使用は推奨されていないようです。 ( この議論 を参照)。

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

8
mookid

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]
1
hugomg

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

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
0
V. Michel