Scala中与F#的异步工作流程等效的是什么?

15

Scala中与F#的async workflows相对应的是什么?

例如,下面的F#代码片段怎样用惯用的Scala方式翻译?

open System.Net
open Microsoft.FSharp.Control.WebExtensions

let urlList = [ "Microsoft.com", "http://www.microsoft.com/"
                "MSDN", "http://msdn.microsoft.com/"
                "Bing", "http://www.bing.com"
              ]

let fetchAsync(name, url:string) =
    async { 
        try
            let uri = new System.Uri(url)
            let webClient = new WebClient()
            let! html = webClient.AsyncDownloadString(uri)
            printfn "Read %d characters for %s" html.Length name
        with
            | ex -> printfn "%s" (ex.Message);
    }

let runAll() =
    urlList
    |> Seq.map fetchAsync
    |> Async.Parallel 
    |> Async.RunSynchronously
    |> ignore

runAll()

3
别告诉别人,但 F# 的工作流只是伪装成单子的东西。如果 Scala 有一些关于单子的语法(我不会说Scala,所以无法确定),那么它们就是等价的。 注:单子 (monads) 是一种用于处理副作用和纯函数式编程的概念。 - R. Martinho Fernandes
2
这并不完全正确 - 它是延续单子加上很多额外的东西,用于异常处理和使用线程池/任务等 - 仅仅重新做这个是非常复杂的。 - Random Dev
@R.MartinhoFernandes:“不要告诉任何人,但 F# 的工作流只是伪装成单子的东西。” 这并不完全正确。计算表达式是 F# 中单子语法的通用框架,其中异步工作流是一种特定形式,旨在使非阻塞代码更易读。 - J D
@CarstenKönig,它不是Continuation Monad(Cont),它们的绑定机制不同,签名完全不同。我更愿意说它基于IO Monad。 - Gus
1个回答

6

你的代码可以使用Futures直接翻译成Scala(虽然会失去一些重要特性):

import scala.actors.Futures
import Futures._

val urlList = Map("Microsoft.com" -> "http://www.microsoft.com/",
                "MSDN" -> "http://msdn.microsoft.com/",
                "Bing" -> "http://www.bing.com")


def fetchAsync(name: String, url: String) = future {
    // lengthy operation simulation
    Thread.sleep(1000)
    println("Fetching from %s: %s" format(name, url))
}

def runAll = 
    //Futures.awaitAll(  <- if you want to synchronously wait for the futures to complete 
    urlList.map{case (name, url) => fetchAsync(name, url)}
    //)

1
@Tomas,你说得完全正确(这就是我上面提到的一些重要区别)。与F# async更直接的类比是Akka的Futures实现(http://doc.akka.io/futures-scala),或者Scalaz中的promises(https://dev59.com/knE95IYBdhLWcg3wHqSl)。 - Vasil Remeniuk
4
未来是一种延续,任何代码都必须在进程或线程上运行。最好的情况是可以进行异步读写,由某些硬件执行,然后通知CPU。话虽如此,future与阻塞I/O交互不良,因为调度程序不会生成新的线程,这很遗憾。 - Daniel C. Sobral
1
@Daniel,我认为最大的抱怨是在stdlib中不可能(轻松地)将续延放在未来完成上。 - Vasil Remeniuk
2
@VasilRemeniuk:“我认为最大的抱怨是在stdlib中不可能(轻松地)在未来的完成上放置一个continuation。”而这只是容易的部分。困难的部分是从一个continuation自动传播异常处理程序到下一个,并进行正确的资源清理。 - J D
2
http://doc.akka.io/docs/akka/2.0.2/scala/futures.html 是Akka futures文档的更新链接。 - Gian
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接