`=<<` 在 Scalaz.Kleisli 中如何工作

How does `=<<` work in Scalaz.Kleisli

对于来自 Scalaz 存储库的 Kleisli 函数组合的以下示例:

  import scalaz._
  import Scalaz._
  import Kleisli._

  import scala.util._

  case class Continent(name: String, countries: List[Country] = List.empty)
  case class Country(name: String, cities: List[City] = List.empty)
  case class City(name: String, isCapital: Boolean = false, inhabitants: Int = 20)

  val data: List[Continent] = List(
    Continent("Europe"),
    Continent("America",
      List(
        Country("USA",
          List(
            City("Washington"), City("New York"))))),
    Continent("Asia",
      List(
        Country("India",
          List(City("New Dehli"), City("Calcutta"))))))

  def continents(name: String): List[Continent] =
    data.filter(k => k.name.contains(name))

  def countries(continent: Continent): List[Country] = continent.countries

  def cities(country: Country): List[City] = country.cities

  def inhabitants(c: City): Int = c.inhabitants
  val allCities = kleisli(continents) >==> countries >==> cities

我得到以下结果:

// fine, expected result for "America"
scala> (allCities =<< List("America")).map(println)
City(Washington,false,20)
City(New York,false,20)
res16: List[Unit] = List((), ())

// confused, why does this bring back the same cities for "Amer"
scala> (allCities =<< List("Amer")).map(println)
City(Washington,false,20)
City(New York,false,20)
res17: List[Unit] = List((), ())

// confused again, has brought back cities for America and Asia - seems to be matching on the first character??
scala> (allCities =<< List("A")).map(println)
City(Washington,false,20)
City(New York,false,20)
City(New Dehli,false,20)
City(Calcutta,false,20)

// confused again, brings back everything:

scala> (allCities =<< List("")).map(println)
City(Washington,false,20)
City(New York,false,20)
City(New Dehli,false,20)
City(Calcutta,false,20)
res19: List[Unit] = List((), (), (), ())

为了完整起见:Kleisli 部分在这里并不真正相关——您看到的行为完全是 continents 方法中 filter 的结果.它 returns 所有名称包含方法参数的大陆,这意味着 AmericaAsia 都返回 "A",所有内容都返回 "",等等