2011-08-30 134 views
3

這裏是我的代碼:如何在F#上創建沒有參數的函數包裝?

let go thriller = 
    work.ListPos.Clear() 
    thriller 
    work.Thread.Start() 

member X.Start() = 
    work.ListPos.Add <| new Packet(connector.Authorize("admin","1")) |> go 

所以這是行不通的。我使用的包裝帶參數如下:

let inconnection thriller = 
    using <| new SqlConnection(insql) <| fun X -> X.Open(); thriller X; 

inconnection <| fun X -> 

我不能使用這種方式不帶參數的,因爲我沒有X(參數),但如何不帶參數創建拉姆達?

謝謝。

回答

4

據我所看到的,你想實現模式「中間孔」 - 這是,運行一些初始化,然後運行用戶指定的函數,然後運行一些清理。

正如dahlbyk已經指出的那樣,你需要通過你的go操作功能unit -> unit。這可以這樣寫:

let go thriller = 
    work.ListPos.Clear() 
    thriller() 
    work.Thread.Start() 

// Use it like this: 
go (fun() -> 
    work.ListPos.Add(new Packet(connector.Authorize("admin","1")) 
) 

另外。你的其他例子並不是真正的慣用F#代碼。該using功能可以用use關鍵字,這是顯著更容易使用替換:

let inconnection thriller = 
    use conn = new SqlConnection(insql) 
    conn.Open() 
    thriller conn 

inconnection (fun conn -> ...) 

更靠譜的選擇。 或者,您也可以使用use關鍵字來處理其他事情,而不是處理像SQL連接這樣的資源。這可能會使您的go功能更好(但取決於您的特定情況)。這個想法是,你就可以這樣寫:

use u = go() // work.ListPos.Clear() gets called here 
work.ListPos.Add(new Packet(connector.Authorize("Admin", "1"))) 
// work.Thread.Start() gets called automatically when 'u' variable goes out of scope 

要做到這一點,你需要定義go爲返回IDisposable執行清理功能:

let go() = 
    work.ListPos.Clear() 
    { new IDisposable with 
     member x.Dispose() = work.Thread.Start() } 
+0

棘手的選擇是有趣的。那麼我可以使用<|去<| fun() -> ...因爲我不需要變量。我需要嘗試一下。我喜歡使用「使用」,因爲它具有開始和結束的功能,我希望能夠將代碼中的某些內容分開。 – Cynede

+0

在棘手的選項中,即使不再使用它,也需要一個變量(這只是'use'的一個屬性)。但是,即使想要更好地控制範圍,也可以使用它。您可以將表達式放在parens中,並從左側進一步縮進以明確定義範圍。 –

+1

我想你可以使用棘手的選項_and_'使用',但這可能不是個好主意(它只是讓事情更復雜)。如果你想使用lambdas,我推薦'go(fun() - > ...)'(如第一個版本),因爲這更直接。 –

6

使用()一個空的拉姆達參數列表或一個空體:

fun() ->() // unit -> unit 
相關問題