Skip to content

Instantly share code, notes, and snippets.

@jcouyang
Last active February 20, 2023 21:09
Show Gist options
  • Save jcouyang/b56a830cd55bd230049f to your computer and use it in GitHub Desktop.
Save jcouyang/b56a830cd55bd230049f to your computer and use it in GitHub Desktop.

Revisions

  1. jcouyang revised this gist Dec 5, 2014. No changes.
  2. jcouyang revised this gist Oct 28, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion why-curry-helps.md
    Original file line number Diff line number Diff line change
    @@ -107,4 +107,4 @@ var plus = ramda.curry(function(a, b){
    <a class="jsbin-embed" href="http://jsbin.com/hamoq/3/embed">JS Bin</a><script src="http://static.jsbin.com/js/embed.js"></script>


    ![Analytics](https://ga-beacon.appspot.com/UA-32314154-5/blogist/emacs-24-4)
    ![Analytics](https://ga-beacon.appspot.com/UA-32314154-5/blogist/why-curry)
  3. jcouyang revised this gist Oct 28, 2014. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions why-curry-helps.md
    Original file line number Diff line number Diff line change
    @@ -105,3 +105,6 @@ var plus = ramda.curry(function(a, b){
    ```

    <a class="jsbin-embed" href="http://jsbin.com/hamoq/3/embed">JS Bin</a><script src="http://static.jsbin.com/js/embed.js"></script>


    ![Analytics](https://ga-beacon.appspot.com/UA-32314154-5/blogist/emacs-24-4)
  4. jcouyang revised this gist Jul 25, 2014. 1 changed file with 2 additions and 3 deletions.
    5 changes: 2 additions & 3 deletions why-curry-helps.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,3 @@
    ## 为什么要柯里化

    还记得 Haskell Curry吗,![](http://s3.amazonaws.com/lyah/curry.png)

    @@ -83,7 +82,7 @@ console.log(concatArray(['1','2','3'], plus(2)))
    有什么不一样呢
    1. 处理数组中字符的函数被提取出来, 作为参数传入
    2. 提取成柯里化的函数, 部分配置好后传入, 好处显而易见, 这下接口非常通畅
    无论是外层调用
    无论是外层调用
    ```
    concatArray(['1','2','3'], multiple(2))
    ```
    @@ -105,4 +104,4 @@ var plus = ramda.curry(function(a, b){
    })
    ```

    <a class="jsbin-embed" href="http://jsbin.com/hamoq/3/embed">JS Bin</a><script src="http://static.jsbin.com/js/embed.js"></script>
    <a class="jsbin-embed" href="http://jsbin.com/hamoq/3/embed">JS Bin</a><script src="http://static.jsbin.com/js/embed.js"></script>
  5. jcouyang revised this gist Jul 3, 2014. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions why-curry-helps.md
    Original file line number Diff line number Diff line change
    @@ -15,7 +15,7 @@ max 3 4

    ### 我们来解一个问题

    1. 写一个函数, 可以连接字符数组, 如 `f(['1','2']) => '12'`
    #### 1. 写一个函数, 可以连接字符数组, 如 `f(['1','2']) => '12'`

    好吧,如果不用柯里化, 怎么写? 啊哈 `reduce`

    @@ -29,7 +29,7 @@ concat(['1','2','3']) // => '123'
    ```
    很简单,对吧.

    2. 现在我要其中所有数字加1, 然后在连接
    #### 2. 现在我要其中所有数字加1, 然后在连接
    ```javascript
    var concatArray = function(chars, inc){
    return chars.map(function(char){
    @@ -40,7 +40,7 @@ var concatArray = function(chars, inc){
    }
    console.log(concatArray(['1','2','3'], 1))// => '234'
    ```
    2. 所有数字乘以2, 再重构试试看
    #### 3. 所有数字乘以2, 再重构试试看

    ```javascript
    var multiple = function(a, b){
  6. jcouyang revised this gist Jul 2, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion why-curry-helps.md
    Original file line number Diff line number Diff line change
    @@ -105,4 +105,4 @@ var plus = ramda.curry(function(a, b){
    })
    ```

    <a class="jsbin-embed" href="http://jsbin.com/hamoq/1/embed?js,console">JS Bin</a><script src="http://static.jsbin.com/js/embed.js"></script>
    <a class="jsbin-embed" href="http://jsbin.com/hamoq/3/embed">JS Bin</a><script src="http://static.jsbin.com/js/embed.js"></script>
  7. jcouyang revised this gist Jul 2, 2014. 1 changed file with 26 additions and 8 deletions.
    34 changes: 26 additions & 8 deletions why-curry-helps.md
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,9 @@
    ## 为什么要柯里化

    还记得 Haskell Curry吗,![](http://s3.amazonaws.com/lyah/curry.png), 多巧啊, 人家姓 Curry 名 Haskell, 难怪 Haskell 语言会自动柯里化, 呵呵. 但是不奇怪吗, 为什么要柯里化呢. 为什么如此重要导致 Haskell 会默认自动柯里化所有函数, 不就是返回一个部分配置好的函数吗.
    还记得 Haskell Curry吗,![](http://s3.amazonaws.com/lyah/curry.png)

    多巧啊, 人家姓 Curry 名 Haskell, 难怪 Haskell 语言会自动柯里化, 呵呵. 但是不奇怪吗, 为什么要柯里化呢. 为什么如此重要导致 Haskell 会默认自动柯里化所有函数, 不就是返回一个部分配置好的函数吗.

    我们来看一个 Haskell 的代码.
    ```haskell
    max 3 4
    @@ -10,8 +13,9 @@ max 3 4

    这里看不出来, 放到`高阶函数`试试. 什么? 看不懂天书 Haskell, 来看看 JavaScript 吧.

    我这里🈶一个问题
    ❔写一个函数, 可以连接字符数组, 如 `f(['1','2']) => '12'`
    ### 我们来解一个问题

    1. 写一个函数, 可以连接字符数组, 如 `f(['1','2']) => '12'`

    好吧,如果不用柯里化, 怎么写? 啊哈 `reduce`

    @@ -25,7 +29,7 @@ concat(['1','2','3']) // => '123'
    ```
    很简单,对吧.

    ❔现在我要所有数字加1
    2. 现在我要其中所有数字加1, 然后在连接
    ```javascript
    var concatArray = function(chars, inc){
    return chars.map(function(char){
    @@ -36,7 +40,7 @@ var concatArray = function(chars, inc){
    }
    console.log(concatArray(['1','2','3'], 1))// => '234'
    ```
    所有数字乘以2, 再重构试试看
    2. 所有数字乘以2, 再重构试试看

    ```javascript
    var multiple = function(a, b){
    @@ -51,8 +55,10 @@ var concatArray = function(chars, inc){
    }
    console.log(concatArray(['1','2','3'], 2)) // => '246'
    ```

    是不是已经看出问题了呢? 如果我在需要每个数字都减2,是不是很麻烦呢.需要将`map` 参数匿名函数中的 multiple 函数换掉. 这样一来`concatArray`就不能同时处理加, 乘和减? 那么怎么能把他提取出来呢? 来对比下柯里化的解法.

    ### 柯里化函数接口
    ```javascript
    var multiple = function(a){
    return function(b){
    @@ -75,8 +81,8 @@ console.log(concatArray(['1','2','3'], multiple(2)))
    console.log(concatArray(['1','2','3'], plus(2)))
    ```
    有什么不一样呢
    1. 处理数组中字符的函数被提取出来, 并作为参数传入
    2. 提取成柯里化的函数, 好处显而易见, 这下接口非常通畅
    1. 处理数组中字符的函数被提取出来, 作为参数传入
    2. 提取成柯里化的函数, 部分配置好后传入, 好处显而易见, 这下接口非常通畅
    无论是外层调用
    ```
    concatArray(['1','2','3'], multiple(2))
    @@ -85,6 +91,18 @@ concatArray(['1','2','3'], multiple(2))
    ```
    chars.map(stylishChar)
    ```
    这些接口都清晰了很多, 不是吗

    <a class="jsbin-embed" href="http://jsbin.com/lepuki/2/embed?js,console">JS Bin</a><script src="http://static.jsbin.com/js/embed.js"></script>
    这就是函数式的思想, 用已有的函数组合出新的函数, 而柯里化每消费一个参数, 都会返回一个新的部分配置的函数, 这为函数组合提供了更灵活的手段, 并且使得接口更为流畅.

    再加上自动柯里化的库 [ramda](https://github.com/CrossEye/ramda), 简直就完美了
    ```
    var multiple = ramda.curry(function(a, b){
    return +b*a + ''
    })
    var plus = ramda.curry(function(a, b){
    return (+b)+a + ''
    })
    ```

    <a class="jsbin-embed" href="http://jsbin.com/hamoq/1/embed?js,console">JS Bin</a><script src="http://static.jsbin.com/js/embed.js"></script>
  8. jcouyang revised this gist Jul 2, 2014. 1 changed file with 88 additions and 1 deletion.
    89 changes: 88 additions & 1 deletion why-curry-helps.md
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,90 @@
    ## 为什么要柯里化

    <a class="jsbin-embed" href="http://jsbin.com/lepuki/2/embed?js,output">JS Bin</a><script src="http://static.jsbin.com/js/embed.js"></script>
    还记得 Haskell Curry吗,![](http://s3.amazonaws.com/lyah/curry.png), 多巧啊, 人家姓 Curry 名 Haskell, 难怪 Haskell 语言会自动柯里化, 呵呵. 但是不奇怪吗, 为什么要柯里化呢. 为什么如此重要导致 Haskell 会默认自动柯里化所有函数, 不就是返回一个部分配置好的函数吗.
    我们来看一个 Haskell 的代码.
    ```haskell
    max 3 4
    (max 3) 4
    ```
    结果都是4, 这有设么用呢.

    这里看不出来, 放到`高阶函数`试试. 什么? 看不懂天书 Haskell, 来看看 JavaScript 吧.

    我这里🈶一个问题
    ❔写一个函数, 可以连接字符数组, 如 `f(['1','2']) => '12'`

    好吧,如果不用柯里化, 怎么写? 啊哈 `reduce`

    ```javascript
    var concatArray = function(chars){
    return chars.reduce(function(a, b){
    return a.concat(b);
    });
    }
    concat(['1','2','3']) // => '123'
    ```
    很简单,对吧.

    ❔现在我要所有数字加1
    ```javascript
    var concatArray = function(chars, inc){
    return chars.map(function(char){
    return (+char)+inc + '';
    }).reduce(function(a,b){
    return a.concat(b)
    });
    }
    console.log(concatArray(['1','2','3'], 1))// => '234'
    ```
    ❔所有数字乘以2, 再重构试试看

    ```javascript
    var multiple = function(a, b){
    return +a*b + ''
    }
    var concatArray = function(chars, inc){
    return chars.map(function(char){
    return multiple(char, inc);
    }).reduce(function(a,b){
    return a.concat(b)
    });
    }
    console.log(concatArray(['1','2','3'], 2)) // => '246'
    ```
    是不是已经看出问题了呢? 如果我在需要每个数字都减2,是不是很麻烦呢.需要将`map` 参数匿名函数中的 multiple 函数换掉. 这样一来`concatArray`就不能同时处理加, 乘和减? 那么怎么能把他提取出来呢? 来对比下柯里化的解法.

    ```javascript
    var multiple = function(a){
    return function(b){
    return +b*a + ''
    }
    }

    var plus = function(a){
    return function(b){
    return (+b)+a + ''
    }
    }
    var concatArray = function(chars, stylishChar){
    return chars.map(stylishChar)
    .reduce(function(a,b){
    return a.concat(b)
    });
    }
    console.log(concatArray(['1','2','3'], multiple(2)))
    console.log(concatArray(['1','2','3'], plus(2)))
    ```
    有什么不一样呢
    1. 处理数组中字符的函数被提取出来, 并作为参数传入
    2. 提取成柯里化的函数, 好处显而易见, 这下接口非常通畅
    无论是外层调用
    ```
    concatArray(['1','2','3'], multiple(2))
    ```
    还是内部的 map 函数
    ```
    chars.map(stylishChar)
    ```

    <a class="jsbin-embed" href="http://jsbin.com/lepuki/2/embed?js,console">JS Bin</a><script src="http://static.jsbin.com/js/embed.js"></script>

  9. jcouyang created this gist Jul 2, 2014.
    3 changes: 3 additions & 0 deletions why-curry-helps.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,3 @@
    ## 为什么要柯里化

    <a class="jsbin-embed" href="http://jsbin.com/lepuki/2/embed?js,output">JS Bin</a><script src="http://static.jsbin.com/js/embed.js"></script>