F#计算表达式可以通过浓厚的语法糖层来隐藏单子语法的复杂性。Scala中是否有类似的东西可用?
我认为是for推导式...
例如:
val f = for {
a <- Future(10 / 2) // 10 / 2 = 5
b <- Future(a + 1) // 5 + 1 = 6
c <- Future(a - 1) // 5 - 1 = 4
} yield b * c // 6 * 4 = 24
val result = f.get
但这样做并不太合适。有更好的语法吗?
例如在Haskell中,你可以这样写:
main = do fromHandle <- getAndOpenFile "Copy from: " ReadMode toHandle <- getAndOpenFile "Copy to: " WriteMode contents <- hGetContents fromHandle hPutStr toHandle contents hClose toHandle putStr "Done."与Scala不同,这个看起来不像是循环。Scala语法似乎与List comprehension耦合过强,这是一个独立的概念。这阻止我编写内部DSL(单子)的形式不奇怪。
for
推导式是正确的。在幕后,它们被展开为map
和flatMap
,这正是 Haskell 中do
表示法的工作方式(除了在 Haskell 中这些方法被称为fmap
和>>=
)。 - Tom Crockettdo
-notation的desugaring实际上并没有使用fmap
,因为没有yield
语句需要它(而且我们不能确定所有的Monad
都是Functor
,尽管它们应该是)... 代替关键字yield
,你只需使用return
函数,当在do
块中作为最后一条语句调用时,相当于一个fmap
。 - Tom Crockett