代码之家  ›  专栏  ›  技术社区  ›  Paul Hollingsworth

什么是“无点”风格(在函数式编程中)?

  •  134
  • Paul Hollingsworth  · 技术社区  · 16 年前

    我最近注意到的一个短语是“无点”风格的概念。..

    首先,有 this 问题,以及 also this one .

    然后,我发现 here 他们提到“另一个值得讨论的话题是作者不喜欢无点风格。”

    为了了解我的水平,我一直在自学Scheme,并编写了一个简单的Scheme解释器。..我理解什么是“隐式”currying,但我不知道任何Haskell或ML。

    7 回复  |  直到 6 年前
        1
  •  76
  •   Nayuki James111    10 年前

    看看 Wikipedia article

    Haskell示例:

    常规(明确指定参数):

    sum (x:xs) = x + (sum xs)
    sum [] = 0
    

    无积分( sum 没有任何明确的论据——它只是与 +

     sum = foldr (+) 0
    

    或者更简单:而不是 g(x) = f(x) ,你可以写 g = f .

    所以是的:它与currying(或函数组合等操作)密切相关。

        2
  •  46
  •   sth    15 年前

    无点风格意味着所定义函数的参数没有明确提及,函数是通过函数组合定义的。

    如果你有两个功能,比如

    square :: a -> a
    square x = x*x
    
    inc :: a -> a
    inc x = x+1
    

    如果你想把这两个函数组合成一个函数来计算 x*x+1 ,您可以将其定义为“点满”,如下所示:

    f :: a -> a
    f x = inc (square x)
    

    x :

    f :: a -> a
    f = inc . square
    
        3
  •  20
  •   InSync Christian C. Salvadó    2 年前

    JavaScript示例:

    //not pointfree cause we receive args
    var initials = function(name) {
      return name.split(' ').map(compose(toUpperCase, head)).join('. ');
    };
    
    const compose = (...fns) => (...args) => fns.reduceRight((res, fn) => [fn.call(null, ...res)], args)[0];
    const join = m => m.join();
    
    //pointfree
    var initials = compose(join('. '), map(compose(toUpperCase, head)), split(' '));
    
    initials("hunter stockton thompson");
    // 'H. S. T'
    

    Reference

        4
  •  8
  •   Rayne    16 年前

    无点风格意味着代码没有明确提及它的参数,即使它们存在并且正在被使用。

    例如:

    myTake = take
    

        5
  •  1
  •   marcelocra    3 年前

    Haskell wiki (摘录如下),由 Petr in a comment .

    在宣言中

    f x = x + 1
    

    我们根据函数f对任意点x的作用来定义函数f。将其与无点版本进行对比:

    f = (+ 1)
    

    其中没有提及函数所作用的值。

    x 上面),因此“无点数”表示法。如果你需要,这个链接会提供更多细节。

        6
  •  1
  •   InSync Christian C. Salvadó    2 年前

    我无法使Brunno提供的javascript示例工作,尽管代码清楚地说明了无点思想(即没有参数)。所以我用 ramda.js

    假设给定一个字符串,我需要找出句子中最长的单词 "Lorem ipsum dolor sit amet consectetur adipiscing elit" 我需要输出类似 { word: 'consectetur', length: 11 }

    如果我使用纯JS风格的代码,我会使用map和reduce函数这样编码

    let str = 'Lorem ipsum dolor sit amet consectetur adipiscing elit'
    let strArray = str.split(' ').map((item) => ({ word: item, length: item.length }))
    let longest = strArray.reduce(
        (max, cur) => (cur.length > max.length ? cur : max), 
        strArray[0])
    console.log(longest)
    

    const R = require('ramda')
    let longest = R.pipe(
      R.split(' '),
      R.map((item) => ({ word: item, length: item.length })),
      R.reduce((max, cur) => (max.length > cur.length ? max : cur), { length: 0 })
    )
    let tmp = longest(str)
    console.log(tmp)
    

    strArray 这是一个额外的奖励(如果我在管道中有超过3个步骤,那么它将成为一个真正的奖励)。

        7
  •  0
  •   InSync Christian C. Salvadó    2 年前

    interface Transaction {
      amount: number;
    }
    
    class Test {
      public getPositiveNumbers(transactions: Transaction[]) {
        return transactions.filter(this.isPositive);
    
        //return transactions.filter((transaction: {amount: number} => transaction.amount > 0));
      }
    
      public getBigNumbers(transactions: Transaction[]) {
        // point-free
        return transactions.filter(this.moreThan(10));
    
        // not point-free
        // return transactions.filter((transaction: any) => transaction.amount > 10);
      }
    
      private isPositive(transaction: Transaction) {
        return transactions.amount > 0;
      }
    
      private moreThan(amount: number) {
        return (transaction: Transaction) => {
          return transactions.amount > amount;
        }
      }
    }
    

    推荐文章