3

タップ関数 (K-Combinator とも呼ばれます) の関数シグネチャが以下にあることを本で読みました。

tap :: (a -> *) -> a -> a

「この関数は、入力オブジェクト a と、a に対して何らかのアクションを実行する関数を受け取ります。指定されたオブジェクトで指定された関数を実行し、オブジェクトを返します。」

  1. 関数シグネチャのアスタリスク (*) の意味を説明してくれる人はいますか?
  2. 以下の実装は正しいですか?
  3. 3 つの実装がすべて正しい場合、いつどれを使用する必要がありますか? 例はありますか?

実装 1:

const tap = fn => a => { fn(a); return a; };

tap((it) => console.log(it))(10); //10

実装 2:

const tap = a => fn => { fn(a); return a; }; 

tap(10)((it) => console.log(it)); //10

実装 3:

const tap = (a, fn) => {fn(a); return a; };

tap(10, (it) => console.log(it)); //10
4

1 に答える 1

6

これは、 Ramda の定義によく似ています。そこ*にあるのはおそらく間違いです。(免責事項: 私は Ramda の作成者の 1 人です。)

// tap :: (a -> b) -> a -> a

最初のような実装:

const tap = fn => a => { fn(a); return a; };

またはRamdaのバージョン:

const tap = curry((fn, a) => { fn(a); return a; });

その署名と一致し、主にデバッグのコンテキストで私見に役立ちます。これを使用して、一時的にロギング ステートメントを機能パイプラインに導入します1 :

// :: Map String User
const users = fetchUsersFromSomewhere();

// :: [Comment] -> [Number]  
const userRatingForComments = R.pipe(
    R.pluck('username'),     // [Comment] -> [String]
    R.tap(console.log),      // for debugging, need to include `bind` in browser envs
//  ^^^^^^^^^^^^^^^^^^      
    R.map(R.propOf(users)),  // [String] -> [User]
    R.pluck('rating')        // [User] -> [Number]
);

ただし、これは実際には K コンビネータではありません。


1このコード サンプルは、Ramda に関する私の古い記事からのものです。

于 2016-07-27T15:06:14.840 に答える