请查看维基百科文章以获取您的定义:
默示编程(point-free programming)是一种编程范式,其中函数定义不包括关于其参数的信息,并使用组合器和函数组合[...]而不是变量。
Haskell示例:
传统方式(您明确指定参数):
sum (x:xs) = x + (sum xs)
sum [] = 0
无参式编程(sum
没有显式参数——它只是一个从0开始的带有+
的fold函数):
sum = foldr (+) 0
甚至更简单:您可以将 g(x) = f(x)
改为 g = f
。sum (x:xs) ...
而不是 sum sum (x:xs) ...
? - Ehtesh Choudhurysum = foldr + 0
吗? - joelittlejohnfoldr
和0
相加,所以中缀函数需要用括号括起来。 - Wezl'点无风格(Point-free style)意味着函数定义时不明确提及函数的参数,并且函数是通过函数组合来定义的。
如果你有两个函数,比如:
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)
点无关(point-free)的替代方案是不讨论参数x
:
f :: a -> a
f = inc . square
//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'
无参风格指的是代码没有明确提到它的参数,尽管它们存在并被使用。
这在Haskell中是可行的,因为函数的工作方式不同于其他编程语言。
例如:
myTake = take
返回一个只需要一个参数的函数,因此除非你想这样做,否则没有理由明确地对参数进行类型定义。
我无法使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个步骤,则它将成为真正的好处)。最好的解释在Haskell wiki中(如下所述),由Petr在一条评论中提出。
该点是一个数学点(上面有In the declaration
f x = x + 1
we define the function f in terms of its action on an arbitrary point x. Contrast this with the points-free version:
f = (+ 1)
where there is no mention of the value on which the function is acting.
x
),因此使用“无点”表示法。如果需要,可以通过链接获取更多详细信息。这里是一个在TypeScript中不使用任何其他库的示例:
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;
}
}
}
你可以看到无参考样式更加"流畅"且易于阅读。
this.moreThan(10)
不是一个命名函数,它是一个柯里化函数,同时也是一个会隐式(因此是无点)以 transaction
作为输入的函数。 - AZ.