W F # wiele funkcji, które pobierają sekwencje, ma sekwencję jako ostatni parametr wspierający potokowanie.Pipelining a częściowa aplikacja do projektowania interfejsu API
Przy projektowaniu API, mogę śledzić ten trend, jak w tym prostym przykładzie machiny państwowej:
type Transition =
{ CurrentState : string; TriggeringEvent : string; NewState : string }
let getNewState currentState triggeringEvent transitions =
let isMatch t =
t.CurrentState = currentState
&& t.TriggeringEvent = triggeringEvent
match transitions |> Seq.tryFind isMatch with
| Some transition -> Some(transition.NewState)
| None -> None
let myTransitions =
[ { CurrentState = "A"; TriggeringEvent = "one"; NewState = "B" };
{ CurrentState = "B"; TriggeringEvent = "two"; NewState = "A" } ]
let result = myTransitions |> getNewState "A" "one"
printfn "%A" result
Tu getNewState
ma podpis:
(string -> string -> seq<Transition> -> string option)
który obsługuje przetwarzanie potokowe:
myTransitions |> getNewState "A" "one"
Ale w niektórych przypadkach sekwencja jest stała, podczas gdy inne argumenty są różne. W przykładzie maszyny stanów, tabela przejściowa (transitions
) zostanie ustalona dla danego komputera stanu. getNewState
zostanie wywołany wiele razy z różnymi stanami i zdarzeniami. Jeśli sekwencja były parametr pierwszy dzwoniący może użyć częściowe zastosowanie:
let getNewState transitions currentState triggeringEvent =
// body same as before
let stateMachine = getNewState myTransitions
let result1 = stateMachine "A" "one"
let result2 = stateMachine "B" "two"
printfn "%A" result1
printfn "%A" result2
Teraz getNewState
ma podpis:
(seq<Transition> -> string -> string -> string option)
i stateMachine
ma podpis:
(string -> string -> string option)
Jak mogę zaprojektować API do obsługi zarówno potokowej jak i częściowej aplikacji, w opcji dzwoniącego?
Twój 'getNewState' jest funkcja zawód związany, więc nie sądzę, nie jest łatwym rozwiązaniem, kim jesteś szukanie. (Zobacz http://msdn.microsoft.com/en-us/library/dd233213.aspx.) Jednym z rozwiązań może być zdefiniowanie nowego typu - powiedzmy rekordu - dla argumentu 'getNewState', aby niezależnie od tego, co jest zmienne, możesz zbudować nowy rekord i przesłać go do 'getNewState'. Możesz też poczekać, aż Petricek lub Pappas udzielą autorytatywnej odpowiedzi. – Shredderroy