在F#中,許多采用序列的函數都將序列作爲支持流水線的最後一個參數。流水線與API設計的部分應用程序
當設計一個API,我可以按照這種趨勢,在這個簡單的狀態機例如:
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
這裏getNewState
有簽名:
(string -> string -> seq<Transition> -> string option)
支持流水線:
myTransitions |> getNewState "A" "one"
但是在某些情況下,序列是恆定的,而其他參數不同。在狀態機示例中,對於給定的狀態機,轉換表(transitions
)將被固定。將使用不同的狀態和事件多次調用getNewState
。如果序列是在第一參數,調用者可以使用部分應用程序:
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
現在getNewState
有簽名:
(seq<Transition> -> string -> string -> string option)
和stateMachine
有簽名:
(string -> string -> string option)
我怎樣才能設計一個API來支持流水線和部分應用程序,在調用者的選擇?
你'getNewState'是讓綁定功能,所以我不認爲有一個簡單的解決方案,你是什麼求。 (請參閱http://msdn.microsoft.com/en-us/library/dd233213.aspx。)一種解決方案可能是爲'getNewState'的參數定義一個新類型(例如記錄),以便無論變化如何,您都可以創建一條新記錄並將其傳遞給'getNewState'。或者您可以等待Petricek或Pappas提供權威答案。 – Shredderroy