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 的电子邮件。因此,使用适当定义的示例邮件 shortMail
和 longMail
,您将获得:
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
通用。
请记住,函数式编程就是关于组合函数。
我在阅读 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 的电子邮件。因此,使用适当定义的示例邮件 shortMail
和 longMail
,您将获得:
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
通用。
请记住,函数式编程就是关于组合函数。