Как сделать функциональную обертку без параметров на F #? - PullRequest
2 голосов
/ 30 августа 2011

вот мой код:

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 (параметра), но как создать лямбду без параметров?

Спасибо.

Ответы [ 2 ]

6 голосов
/ 30 августа 2011

Используйте () для пустого списка параметров лямбда или для пустого тела:

fun () -> ()  // unit -> unit
3 голосов
/ 30 августа 2011

Насколько я вижу, вы пытаетесь реализовать шаблон "дыра в середине" - то есть выполнить некоторую инициализацию, затем запустить функцию, указанную пользователем, и затем выполнить некоторую очистку.

Как уже указывал 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() }
...