2011-04-07 73 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