Scala 中的 F# seq monad 等价于什么

问题描述 投票:0回答:2

我正在尝试从 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 f# seq scala-streams
2个回答
3
投票

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))
}

0
投票

回复:你的第二个问题,你是否可以在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 理解,但管理这些理解周围的资源必须单独完成。

© www.soinside.com 2019 - 2024. All rights reserved.