`=<<` 在 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 所有名称包含方法参数的大陆,这意味着 America
和 Asia
都返回 "A"
,所有内容都返回 ""
,等等
对于来自 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 所有名称包含方法参数的大陆,这意味着 America
和 Asia
都返回 "A"
,所有内容都返回 ""
,等等