4

我在阅读the-neophytes-guide-to-scala-part-10时遇到了以下代码。

type EmailFilter = Email => Boolean

val minimumSize: Int => EmailFilter = n => email => email.text.size >= n

我理解为接收电子邮件返回布尔值的函数创建类型别名 EmailFilter 的第一行。但我不明白我们将电子邮件和数字作为输入并通过检查大小返回布尔值的第二行。请解码第二行并向我解释这个函数的语法糖代码。

4

2 回答 2

14

没有任何语法糖,只有原始的 lambda 表达式。如果将type EmailFilter定义插入到第二行的类型中,您将获得

Int => (Email => Boolean)

这与 相同(因为 的右结合性=>

Int => Email => Boolean 

这与

n   => email => (email.text.size >= n)

它本质上只是说:给定一个数字n,创建一个电子邮件过滤器,当且仅当电子邮件的长度至少为 时,给定一个email返回truen的电子邮件过滤器,例如

minimumSize(100)

返回一个行为就像的闭包

email => email.text.size >= 100

即它过滤所有长度大于或等于 100 的电子邮件。因此,通过适当定义的示例邮件shortMaillongMail,您将获得:

minimumSize(100)(shortMail) // false
minimumSize(100)(longMail) // true
于 2018-05-17T14:07:20.930 回答
5

minimumSize函数是一个柯里化函数。

Currying 是一种将函数调用拆分为多个顺序子函数调用的方法。

curry 函数有很多很好的优点,一个是它可以让你的函数更加可组合,通过延迟真实的数据源。

让我们描述一下用法:

n => email => email.text.size >= n   

我们可以首先通过传递一个参数来调用这个函数n

minimumSize(2) // partially applies the minimumSize function with 2 as n 

此时你会得到:

val nextFunction = email => email.text.size >= 2

接下来你nextFunction用电子邮件打电话:

nextFunction(Email("anemail@domain.com"))

这时你会得到一个布尔值:

val bool = Email("anemail@domain.com").text.size >= 2

所以如果我们总结一下:

我们从一个开始Int,然后是一个Email,然后是一个Boolean

Int => Email => Boolean

通过更仔细地查看这个签名,你会认出这个EmailFilter签名。
让我们替换:

Int => EmailFilter 

这个想法是将EmailFilter行为作为模板,您可以使用一些更高的功能进行参数化。
在这里,我们参数化了电子邮件文本大小比较,以便我们可以保持EmailFilter通用性。

请记住,函数式编程就是组合函数。

于 2018-05-17T14:07:27.760 回答