您的位置:首页 > 其它

高阶函数的复用与组合

2015-08-23 20:20 281 查看
原文

http://danielwestheide.com/blog/2013/01/23/the-neophytes-guide-to-scala-part-10-staying-dry-with-higher-order-functions.html

这个是边看边记录的

case class Email(subject: String,text: String,sender: String,recipient: String)

object Demo {
//从圆点开始抽象,我们要写的是Email => Boolean的扩展,即我们提供一个Email给表达式之外,
//让后返回boolean,我们根据该boolean继续我们的工作,而函数之外就可以根据这个email组各种
//逻辑判断
type EmailFilter = Email => Boolean
def newEmailsForUser (mails:Seq[Email],f:EmailFilter) = mails.filter(f)
val sendbyOneOf:Seq[String] => EmailFilter = senders => email => senders.contains(email.sender)
val notsendByAnyOf:Seq[String] => EmailFilter = senders => email => !senders.contains(email.sender)
val miniMunSize:Int => EmailFilter = n => email => email.text.size >= n
val maxMunSize:Int => EmailFilter = n => email => email.text.size <= n
val emailFilter:EmailFilter = notsendByAnyOf(Seq("1johndoe@example.com"))
//为了重用size的Email判断这一环节的code

type sizeCheck = Int => Boolean
val sizeConstraint:sizeCheck => EmailFilter = f => email => f(email.text.size)

val minimum2Size:Int => EmailFilter = n => sizeConstraint(_ >= n)
val maxmum2Size:Int => EmailFilter = n => sizeConstraint(_ <= n)

def complement[A](predicate: A => Boolean) = (a: A) => !predicate(a)
//由于sendbyOneOf的结果是A => Boolean,andThen使得成为andThen的参数
//也就是f andthen g 是把g应用到f的结果上
val notSentByAnyOf2 = sendbyOneOf andThen(complement(_))
//或者可以直接这样编写
val notSentByAnyOf3 = sendbyOneOf andThen(f => (x:Email) => !f(x))

val mails = Email(
subject = "It's me again, your stalker friend!",
text = "Hello my friend! How are you?",
sender = "johndoe@example.com",
recipient = "me@example.com"
)::Nil
//只要有一个满足条件就保留
def any[A](predicates: (A => Boolean)*): A => Boolean = a => predicates.exists(pred => pred(a))
//都不满足条件,就是对any的结果进行反转
def none[A](predicates: (A => Boolean)*) = complement(any(predicates: _*))
//全部满足条件,就是每个条件的false的反转,每个条件都false即none的结果,所以只要对每个A => Boolean结果反转,在用none求结果
def every[A](predicates: (A => Boolean)*) = none(predicates.view.map(complement(_)): _*)

//Composing a transformation pipeline
val addMissingSubject = (email: Email) =>
if (email.subject.isEmpty) email.copy(subject = "No subject")
else email
val checkSpelling = (email: Email) =>
email.copy(text = email.text.replaceAll("your", "you're"))
val removeInappropriateLanguage = (email: Email) =>
email.copy(text = email.text.replaceAll("dynamic typing", "**CENSORED**"))
val addAdvertismentToFooter = (email: Email) =>
email.copy(text = email.text + "\nThis mail sent via Super Awesome Free Mail")

//将同参数的f进行组合
val pipeline = Function.chain(Seq(
addMissingSubject,
checkSpelling,
removeInappropriateLanguage,
addAdvertismentToFooter))
def main(args: Array[String]) {
newEmailsForUser(mails,emailFilter).foreach{ x=>
println(x)
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: