Tap(K-combinator)

时间:2016-07-27 13:42:10

标签: javascript functional-programming function-signature k-combinator

我在书中读到了tap功能的功能签名(也称为K-Combinator)如下:

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

"此函数接受输入对象a和对a执行某些操作的函数。它使用提供的对象运行给定函数,然后返回对象。"

  1. 有人可以帮我解释一下函数签名中star(*)的含义是什么吗?
  2. 以下实施是否正确?
  3. 如果所有三个实现都正确,哪个应该在什么时候使用?有什么例子吗?
  4. 实施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
    

1 个答案:

答案 0 :(得分:4)

这看起来很像Ramda definition。那里的*可能是个错误。 (免责声明:我是Ramda的作者之一。)应该阅读

// 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的old article

相关问题