我最近注意到的一个短语是“无点”风格的概念......
首先,有this个问题和also this one。
然后,我发现here他们提到“可能值得讨论的另一个话题是作者不喜欢点自由风格。”
什么是“免费”风格?有人可以给出简明的解释吗?它与“自动”曲线有关吗?
为了了解我的水平 - 我一直在教自己Scheme,并编写了一个简单的Scheme解释器...我理解“隐含”currying是什么,但我不知道任何Haskell或ML。< / p>
答案 0 :(得分:57)
只需查看Wikipedia article即可获得您的定义:
隐性编程(无点编程)是一种编程范例,其中函数定义不包含有关其参数的信息,使用组合器和函数组合而不是变量。
Haskell示例:
常规(您明确指定参数):
sum (x:xs) = x + (sum xs)
sum [] = 0
无点(sum
没有任何明确的参数 - 它只是+
从0开始的折叠:
sum = foldr (+) 0
甚至更简单:您可以只写g(x) = f(x)
而不是g = f
。
所以是的:它与currying(或函数组合等操作)密切相关。
答案 1 :(得分:25)
无点样式意味着未明确提及所定义函数的参数,该函数是通过函数组合定义的。
如果你有两个功能,比如
square :: a -> a
square x = x*x
inc :: a -> a
inc x = x+1
如果你想将这两个函数组合成一个计算x*x+1
的函数,你可以将它定义为“point-full”,如下所示:
f :: a -> a
f x = inc (square x)
无点替代方案不是谈论论证x
:
f :: a -> a
f = inc . square
答案 2 :(得分:8)
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'
答案 3 :(得分:4)
点自由样式意味着代码没有明确提及它的参数,即使它们存在并且正在被使用。
由于函数的工作方式,这在Haskell中有效。
例如:
myTake = take
返回一个带有一个参数的函数,因此除非你只是想要,否则没有理由显式地输入参数。
答案 4 :(得分:0)
尽管代码清楚地说明了无意义的想法(即没有参数),但我无法使提供Brunno的javascript示例有效。因此,我使用ramda.js提供了另一个示例。
假设我需要找出一个句子中最长的单词,给定字符串"Lorem ipsum dolor sit amet consectetur adipiscing elit"
,我需要输出类似{ word: 'consectetur', length: 11 }
如果我使用普通的JS样式代码,则将使用映射和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)
在使用ramda时,我仍然使用map和reduce,但是我将像这样编写代码
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)
我会争辩说,我的ramda代码的要旨是将我的函数链接在一起的管道,它使我的目标更加清晰。无需创建临时变量strArray
是一项奖励(如果我在管道中有3个以上的步骤,那么它将成为真正的奖励)。
答案 5 :(得分:-1)
以下是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;
}
}
}
你可以看到无点样式更“流畅”,更容易阅读。