6 7 3 實現列表函式

2021-06-27 02:56:40 字數 1949 閱讀 8985

6.7.3 實現列表函式

剛才我們看到的篩選和對映函式,沒有展示如何實現,現在,我們要看乙個在第三章開始建立的函式。因為所有的列表處理函式都有類似的結構,看過下面的示例以後,實現其他任何函式也是可能的。

在第三章,我們寫的函式,能夠計算列表中的所有元素的和或積;隨後,我們就意識到它可能比開始所表現的更有用:我們看到,它還能用來查詢最小或最大元素。那時,我們沒有討論過泛型,因此,函式只處理整數。在清單 6.22 中,有乙個類似的函式,沒有型別批註,原始約束自動泛型化。

清單 6.22 泛型列表聚合 (f# interactive)

> let rec fold f init list =

match list with

| –> init

|head::tail –>

let state = f init head

fold f state tail

val fold : ('a -> 'b -> 'a) -> 'a-> 'b list -> 'a    [1] <-- 顯示的型別簽名

這個實現非常像第三章的;更重要的是,我們去掉了型別批註,因此,推斷的簽名更通用[1]。現在函式引數列表值的型別為 'b,聚合產生的值可以有不同型別(型別引數為 'a)。處理函式的引數值為當前的聚合結果(型別為 'a),和列表('b)中的乙個元素,返回乙個新的聚合的結果。

我們很快會看到,使用泛型使聚合更有用;在 f# 庫中也有,處理不可變 f# 列表型別的版本位於 list 模組。下面的**片斷顯示了原來第三章中的用法,計算列表中所有元素的積:

> [ 1 .. 5 ] |> list.fold (*) 1

val it : int = 120

由於將要處理泛型函式,編譯器必須首先推斷出型別引數的型別。這裡,我們處理的是整數列表,所以,引數 'b 是 int,結果也是整數,所以 'a 也是 int。清單 6.23 顯示其他一些使用 fold 的例子。

清單 6.23 使用 fold 的示例 (f# interactive)

> places |> list.fold (fun sum (_,pop) -> sum + pop) 0;;    [1]

val it : int = 9080788

> places |> list.fold (fun s (n, _)-> s + n + ", ") "";;   [2]

val it : string =

"seattle, prague, new york,grantchester, cambridge, "

> places

|> list.fold (fun (b,str) (name, _) –>    [3]

let n = if b then name.padright(20) else name + "\n"

(not b, str+n)

) (true, "")    <-- 指定初始元組值

|> snd    [4]

|> printfn "%s";;   <-- 輸出格式化後的字串

seattle prague

new york grantchester

cambridge

在所有示例中,我們使用的都是我們定義的有關城市資訊的集合,因此,列表的型別都相同。這樣,引數 'b 的實際型別總是 (string * int) 元組;然而,聚合的結果不同。第一種情況[1],我們只計算人口的和,因此,結果的型別是 int;第二個示例[2],我們要構建有城市名字的字串,因此,用空字串開始聚合。lambda 函式作為第乙個引數值,追加當前處理的城市名字和分隔符。

在最後乙個示例中[3],我們實現的版本改進了格式,將城市名字分成兩列,因此,lambda 函式執行兩個交替操作。第一種情況,用空格填充名字(填充第一列),第二種情況,則將新增換行符(以結束行)。這是通過使用 bool 型別的臨時值完成的,最初設定為 true,然後,在每次迭代時切換。聚合後的值包含了交替的臨時值和結果字串,因此,在結束時,需要從元組中刪除臨時值。

6 73 爆記憶體函式例項 6分

在這裡插入 片6 73 爆記憶體函式例項 6分 本題要求實現乙個遞迴函式,使用者傳入非負整型引數n,使用者依次輸出1到n之間的整數。所謂遞迴函式就是指自己呼叫自己的函式。說明 1 遞迴函式求解問題的基本思想是把乙個大規模問題的求解歸結為乙個相對較小規模問題的求解,小規模歸結為小小規模,以此類推,直至...

可變引數列表函式實現

如題 我們在寫可變引數列表函式之前,先來了解一下什麼是可變引數列表函式。我們在c語言程式設計中有時會遇到 一些引數個數可變的函式,例如printf 函式,其函式原型為 int printf const char format,它除了有乙個引數format固定以外,後面跟的引數個數和型別是可變的 用三...

C C 函式變長引數列表實現

在c編譯器通常提供了一系列處理可變引數的巨集,實現就像printf 那樣的變長引數列表,這樣可以遮蔽不同的硬體平台造成的差異,增加程式的可移植性。這些巨集包括va start va arg和va end等,這些巨集都是在標頭檔案裡定義的。採用ansi標準形式時,引數個數可變的函式的原型宣告是 typ...