2011-04-07 76 views
15

什么是F#异步工作流的Scala等价物?什么是F#异步工作流程的Scala等价物?

例如,如何将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对Monad有一些语法(我不会说Scala,所以我不能说),那么这就相当于。 – 2011-04-07 10:48:30

+2

这不是完全真实的 - 它是继续monad加上很多额外的东西,用于异常处理和ThreadPool /任务等的使用 - 这是不平凡的,只是重做这个 – Carsten 2012-06-25 11:06:39

+0

@ R.MartinhoFernandes“不要告诉任何人,但F#的工作流程只是变相的monad“。这是不正确的。 *计算表达式*是F#中monadic语法的一般框架,其中异步工作流是一种特殊形式,旨在使非阻塞代码更具可读性。 – 2012-06-25 17:37:12

回答

6

你的代码或多或少直接可以使用转换为斯卡拉Futures(带丢了,虽然一些重要的功能):

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

我认为F#异步wokflows的意义在于,您可以轻松编写不会阻塞线程的代码(因为它使用延续而不是线程)。我对Scala并不熟悉,但我认为这种未来实现了这一点 - 因为未来只会在单线程上运行,直到完成,不是吗? – 2011-04-07 20:49:50

+1

@托马斯,你是绝对正确的(这就是我之前提到的一些重要差异存在的原因)。对F#异步的更直接的模拟将是Akka的期货实现(http://doc.akka.io/futures-scala)或斯卡拉斯的承诺(http://stackoverflow.com/questions/2446770/how-to-split -and-调度-AN-异步控制流-使用-延续)。 – 2011-04-07 21:53:49

+4

@Tomas未来是一个延续,任何代码都必须在进程或线程上运行。充其量,可以有异步读取和写入,这是由一些硬件执行,然后通知给CPU。也就是说,期货与阻止I/O交互不良 - 因为调度器不会产生新的线程 - 这是一个耻辱。 – 2011-04-07 22:15:28