高阶函数的复用与组合

原文

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)
    }
  }
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值