2011-08-30 139 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 
相关问题