【问题标题】:Understanding types in higher order functions in Scala理解 Scala 中高阶函数的类型
【发布时间】:2014-08-30 16:44:59
【问题描述】:

我正在自学 Scala(来自多年的 Java),我遇到了以下代码,我无法完全理解:

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

type EmailFilter = Email => Boolean
def newMailsForUser(mails: Seq[Email], f: EmailFilter) = mails.filter(f)

val sentByOneOf: Set[String] => EmailFilter =
  senders => email => senders.contains(email.sender)

val notSentByAnyOf: Set[String] => EmailFilter =
  senders => email => !senders.contains(email.sender)

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

我觉得难以理解的部分是缺少类型定义的 val:

val sentByOneOf: Set[String] => EmailFilter =
  senders => email => senders.contains(email.sender)

我使用 def 创建了相同的函数,我可以理解:

def sentByOne(senders: Set[String], email: Email): (Set[String] => EmailFilter) = {
  senders => email => senders.contains(email.sender)
}

以前版本中的类型来自哪里?另外,后一个版本更可取吗?

【问题讨论】:

    标签: scala types higher-order-functions


    【解决方案1】:

    简短的回答,在这个定义中:

    val sentByOneOf: Set[String] => EmailFilter =  
      senders => email => senders.contains(email.sender)
    

    扩展到:

    val sentByOneOf: Set[String] => Email => Boolean = 
      senders => email => senders.contains(email.sender)
    

    类型在: 之后定义为Set[String] =&gt; EmailFilter。所以传递给sentByOneOf 的第一个值是Set[String],第二个是EmailFilter 类型,它是Email =&gt; Boolean 的别名。

    加长版:

    与 Scala 中的所有变量/值一样,类型可以像本例一样在冒号后指定,也可以从它所引用的表达式中推断出来。所以在这里:

    val sentByOneOf = (senders: Set[String]) => (email: Email) => 
      senders.contains(email.sender)
    

    sentByOneOf 的类型也将被推断为sentByOneOf: Set[String] =&gt; (Email =&gt; Boolean),其中Email =&gt; Boolean 的别名定义为EmailFilter

    在 scala function values 中,这实际上是你在这里所拥有的,实际上是 FunctioN 类的实例,其中 N 是变量的数量。所以你的函数sentByOneOf实际上是这样的:

    val sentByOneOf = new Function2[Set[String], Email, Boolean] { 
      def apply(senders: Set[String], email: Email, pred: => Boolean): Boolean = senders.contains(email.sender)
    }
    

    顺便说一句,您选择了很棒的系列文章,但对于第一次使用 Scala 来说相当困难 :)

    【讨论】:

    • sendersemail 的类型在哪里?
    猜你喜欢
    • 2020-08-18
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-25
    相关资源
    最近更新 更多