Scala with Cats 一书中的代码示例中额外的 _ 是什么?

What is the extra _ in this code sample from the Scala with Cats book?

我正在阅读这里提供的 Scala with Cats 书:https://books.underscore.io/scala-with-cats/scala-with-cats.html

书中有一个代码示例我有疑问。

基本上,代码中多了一个下划线,我不明白其用途。是错字,还是下划线有什么用?

import cats.Monoid
import cats.instances.int._        // for Monoid
import cats.instances.invariant._  // for Semigroupal
import cats.instances.list._       // for Monoid
import cats.instances.string._     // for Monoid
import cats.syntax.apply._         // for imapN

case class Cat(
  name: String,
  yearOfBirth: Int,
  favoriteFoods: List[String]
)

val tupleToCat: (String, Int, List[String]) => Cat =
  Cat.apply _

val catToTuple: Cat => (String, Int, List[String]) =
  cat => (cat.name, cat.yearOfBirth, cat.favoriteFoods)

implicit val catMonoid: Monoid[Cat] = (
  Monoid[String],
  Monoid[Int],
  Monoid[List[String]]
).imapN(tupleToCat)(catToTuple)

我指的是 tupleToCat 的定义 class。 Cat.apply后面的下划线是什么意思?

在 scala lambda 函数(或匿名函数,例如您的示例中的 tupleToCat)中,_ 充当该函数的参数列表的名称。所以在那种情况下 Cat.apply _ 意味着调用 Cat.apply 并将所有参数传递给 tupleToCat

下划线比它更强大。参见 here for more info

是方法转函数的方式。 Cat.apply 是伴随对象 Cat 的一个方法,它接收一个 String(名字)、一个 Int(出生年份)和一个 List[String](最喜欢的食物)和 returns 一个 Cat。 当你Cat.apply _将方法转换为函数时。

您还可以使用 curried,然后使用部分应用函数来获得一个接收 yearOfBirth 和最喜欢的食物列表以及 returns 一只名叫汤姆的猫的函数。

val curried: String => Int => List[String] => Cat = Cat.curried

val alwaysTom = curried("Tom")

val tom = alwaysTom(1)(List("fish"))
val olderTom = alwaysTom(10)(List("fish","rice"))

你也可以在没有curried

的情况下使用部分应用函数
val alwaysTom: (Int, List[String]) => Cat = Cat.apply("tom",_:Int,_:List[String])