8.1.4 在 f# 中使用函式列表
首先,我們宣告乙個表示有關客戶資訊的型別。客戶端有相當多屬性,所以,最自然的表示將是 f# 的記錄型別,我們在前一章中已經看過。清單 8.4 顯示了這個型別宣告,和所建立的示例客戶的**。
listing 8.4 client record type and sample value (f# interactive)
> type client =
;; type client = (...)
> let john =
;; val john : client
這裡沒有什麼新東西,我們宣告乙個型別,並建立它的例項。為使這個清單更短,我們沒有為每個屬性使用單獨的行,不論是在宣告型別時,還是在創新值時。這是有效的 f#,但我們必須在屬性之間加上分號。在輕量級的語法中,編譯器會自動在行尾將加上(如果分號是需要的),但是,當換行不能幫助編譯器時,必須要明確寫上分號。
清單 8.5 完成這個示例。首先,它建立測試列表,然後,決定建議提供是否貸款給前面清單中的示例客戶(john doe) 。
listing 8.5 executing tests (f# interactive)
> let tests =
[ (fun cl -> cl.criminalrecord = true);
(fun cl -> cl.income < 30000);
(fun cl -> cl.usescreditcard = false);
(fun cl -> cl.yearsinjob < 2) ];;
val tests : (client -> bool) list
> let testclient(client) =
let issues = tests |> list.filter (fun f -> f (client))
let suitable = issues.length <= 1
printfn "client: %s/noffer a loan: %s (issues = %d)" client.name
(if (suitable) then "yes" else "no") issues.length;;
val testclient : client –> unit
> testclient(john);;
client: john doe
offer a loan: yes (issues = 1)
這使用了建立列表常規語法,來初始化測試,使用 lambda 函式的語法寫的。我們不必寫任何型別注釋,f# 仍然正確推斷出列表的型別。f# 的型別推斷足夠聰明,能使用訪問成員的名字推斷出我們想要使用的記錄型別。
在 c# 版本中,我們使用 count 方法統計測試失敗數。f# 沒有等效的函式,我們既可以實現它,也可以組合其他標準的函式,獲得相同的結果。這裡,我們採用了第二種方法。首先,我們得到被認為是不安全的客戶測試列表,這些通過使用 list.filter 返回測試,然後,我們使用 length 屬性,得到問題的數量。
在本節中,我們學習了如何設計和處理基本的面向行為的資料結構——函式列表——在 c# 和 f# 中。在側邊欄"無點式程式設計「中,我們會看到清單 8.5 中用到的重要的函式技術。在下一節中,我們會繼續有關常見做法的討論,就像我們討論兩個物件導向的設計模式和相關的函式式結構一樣。
無點式程式設計
我們已經見過很多例子,當呼叫高階函式時,不必顯式寫出 lambda 函式,那麼,這在清單 8.5 中可能嗎?這種寫程式的方式被稱為無點(point-free),因為,我們處理的資料結構,包含值(比如列表),但是,我們從來沒有給這個結構中的值指定任何名字(特定的"點") 。讓我們用示例來演示這一概念,我們已經看過了:
[1 .. 10] |> list.map ((+) 100)
places |> list.map (snd >> statusbypopulation)
在第一種情況下,我們處理乙個數字集合,但是,沒有任何符號表示列表中的值。第二種情況有的類似,除了我們處理的列表是元組以外,而且,沒有任何的符號來表示元組或元組中的任何元素。
這種無點式之所以可能,是由於幾個程式設計技術。第乙個是使用偏函式應用,是基於有大量引數的函式,建立有必需數量引數的函式的一種方法。在我們的示例中,我們把中綴運算子 (+) 也看做乙個普通函式,第二個使用函式組合,這是另一項重要的構建函式技術,不必顯式引用這個函式處理的值。
現在,讓我們看看如何重寫清單 8.5 的示例。首先,我們要用流運算子來重寫這個 lambda 函式。
把:(fun f -> f client)
重寫成:
(fun f -> client |> f)
這兩個函式意思相同。我們幾乎完成,因為,流運算子取這個 client 作為第乙個引數值,乙個函式作為第二個引數值。如果我們使用偏應用來只指定第乙個引數值(client),我們會得到乙個函式,它取函式 (f) 作為引數值,並將它應用到 client:
tests |> list.filter ((|>) client)
無點式程式設計應始終用在刀刃上。雖然它使**更簡潔、典雅,但是,有時很難閱讀和推理,我們在這裡已經表明是不平凡的。無點式對於某些領域的程式設計是重要的,在第 15 章,我們將會看到它在開發特定域語言時的用途。
8 1 4 在 F 中使用函式列表
8.1.4 在 f 中使用函式列表 首先,我們宣告乙個表示有關客戶資訊的型別 客戶有很多屬性,因此,用f 的記錄型別表示最自然的選擇,我們在前一章已經看過。清單 8.4 顯示了型別宣告,和所建立樣本客戶的 清單 8.4 client 記錄型別和樣本值 f interactive type clien...
QT 內部使用函式列表
滑鼠事件 void mousepressevent qmouseevent event 單擊 void mousereleaseevent qmouseevent event 釋放 void mousedoubleclickevent qmouseevent event 雙擊 void mousem...
Python在函式中使用 和 接收元組和列表
當要使函式接收元組或字典形式的引數的時候,有一種特殊的方法,它分別使用 和 字首。這種方法在函式需要獲取可變數量的引數的時候特別有用。注意 1 由於在args變數前有 字首,所有多餘的函式引數都會作為乙個元組儲存在args中。如果使用的是 字首,多餘的引數則會被認為是乙個字典的健 值對。2 對於de...