我正在尝试从 F# 迁移到 Scala。在F#中,我们可以轻松地用计算表达式或monad创建一个seq。例如:
let myseq = seq {
let mutableList = List()
for i = 0 to 100 do
mutableList.append(i)
yield sum(mutableList)
}
myseq |> Seq.iter println
我读过关于 scala
Stream
的内容,但我不确定如何正确使用它,就像上面的示例一样,其中包含一些状态在 seq 生成期间不断更新。
另一个例子是在 seq 中进行一些初始化和清理工作:
let myseq = seq {
let file = open(path)
while (x = read(file)) do
yield x
file.close() }
我们可以在 scala 中做到这一点吗?
Scala 具有使用 for
和
yield
关键字的 序列推导式,如以下示例所示:
object ComprehensionTest extends App {
def even(from: Int, to: Int): List[Int] =
for (i <- List.range(from, to) if i % 2 == 0) yield i
Console.println(even(0, 20))
}
回复:你的第二个问题,你是否可以在scala中做到这一点。回复晚了,但我最近问了自己同样的问题。
let file = open(path) while (x = read(file)) do yield x file.close() } ```
是的,你可以做到,但是......它需要更多的工作来处理错误路径。
首先,如果您只想从文本文件中获取行,您可以使用 scala.io.Source.fromFile(...).getLines().
查看我的 answer,了解在序列中嵌入语句时 F# 编译器生成的内容。请注意,如果文件不存在,F# 代码可能会崩溃并引发异常。
回到 scala,您需要弄清楚如何处理错误情况,当然还有愉快的路径。 Alvin Alexander 有一本非常好的书,《简化函数式编程》,他在其中讨论了处理错误的各种方法,即使用 Option、Try、Either。当然,您始终可以忽略这些并诉诸例外。
所以,在我看来,正如 Aaron 回答的那样,与
seq {...}
计算表达式最接近的工件是 for 理解,但管理这些理解周围的资源必须单独完成。