我读The Neophyte's Guide to Scala Part 8: Welcome to the Future和代码的一部分我感到困惑的是:为什么尝试在此参数不工作时尝试工作?
import scala.util.Try
object CoffeeSync extends App {
// Some type aliases, just for getting more meaningful method signatures:
type CoffeeBeans = String
type GroundCoffee = String
case class Water(temperature: Int)
type Milk = String
type FrothedMilk = String
type Espresso = String
type Cappuccino = String
// dummy implementations of the individual steps:
def grind(beans: CoffeeBeans): GroundCoffee = s"ground coffee of $beans"
def heatWater(water: Water): Water = water.copy(temperature = 85)
def frothMilk(milk: Milk): FrothedMilk = s"frothed $milk"
def brew(coffee: GroundCoffee, heatedWater: Water): Espresso = "espresso"
def combine(espresso: Espresso, frothedMilk: FrothedMilk): Cappuccino = "cappuccino"
// going through these steps sequentially:
def prepareCappuccino(): Try[Cappuccino] = for {
ground <- Try(grind("arabica beans"))
water <- Try(heatWater(Water(25)))
espresso <- Try(brew(ground, water))
foam <- Try(frothMilk("milk"))
} yield {
combine(espresso, foam)
}
所有这一切工作正常,但我感到困惑的是,为什么Try
作品中对于Fomprehension?
grind("arabica beans")
应该返回类型GroundCoffee
的值,它是String
的类型别名。我知道For Comprehensions遍历一个Collection,并且它被赋值为一个值,并且该Try(grind(...))
被视为一个元素的Collection,因此ground
表示元素“unwrapped”。
但是,如果这种解释是完全的,那么我就不会当我做下面的得到一个编译错误:
// going through these steps sequentially:
def prepareCappuccino(): Try[Cappuccino] = for {
// Replaced Try with Seq
ground <- Seq(grind("arabica beans"))
water <- Try(heatWater(Water(25)))
espresso <- Try(brew(ground, water))
foam <- Try(frothMilk("milk"))
} yield {
combine(espresso, foam)
}
这给了我以下内容:
<console>:41: error: type mismatch;
found : scala.util.Try[CoffeeSync.Cappuccino]
(which expands to) scala.util.Try[String]
required: scala.collection.GenTraversableOnce[?]
water <- Try(heatWater(Water(25)))
^
<console>:40: error: type mismatch;
found : Seq[Nothing]
required: scala.util.Try[CoffeeSync.Cappuccino]
(which expands to) scala.util.Try[String]
ground <- Seq(grind("arabica beans"))
^
所以我猜是什么我真的问的是为什么我的Seq[GroundCoffee]
转换为Seq[Nothing]
?感谢您的帮助。
还有一个'toOption'方法你可以用它来完成这项工作。 “Try”实际上不是一个Monad,它可以防止设计级别之后的构图。详情请浏览:https://gist.github.com/ms-tg/6222775。 – flavian
@ ka4eli,谢谢您的详尽解答!正确回答我的问题。我认为最好总是认为理解只是语法上的'map'和'flatMap'。 –