Scala Currying 和函数文字

Scala Currying and function literals

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

type EmailFilter = Email => Boolean

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

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

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

Int => (Email => Boolean)

相同(因为 => 的右结合性)
Int => Email => Boolean 

这完全符合

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

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

minimumSize(100)

returns 一个行为类似于

的闭包
email => email.text.size >= 100

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

minimumSize(100)(shortMail) // false
minimumSize(100)(longMail) // true

minimumSize 函数是一个 curried 函数。

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

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 通用。

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