F 程式設計 函式式程式設計之Records

2021-05-13 02:58:37 字數 2610 閱讀 3887

當你想把資料組成乙個結構化的格式,而不需要太複雜的語法時,你可以使用f#中的record型別。record型別與c語言的struct型別基本一樣,儲存一組型別的值,通過欄位的值來獲取。定義乙個record型別很簡單,只需要在大括號內定義系列的名稱/型別就可以。要例項化乙個record,只需要提供對應的字段以及值即可,剩下的型別推斷系統會根據你的輸入來自動判斷,比如:

> type personrec = ;;

type personrec =

> let steve = ;;

val steve : personrec =

> printfn "%s is %d years old" steve.first steve.age;;

steve is 21 years old

val it : unit = ()

cloning records

利用關鍵字"with"可以很容易的實現記錄轉殖,比如上面的那個steve有乙個雙胞胎哥哥,可以用下面的**來例項化他哥哥,^_^:

> let bill = ;;

val bill : personrec =

如果轉殖時需要更改多個欄位的值,只需要用逗號分隔開來。

pattern matching

record也可用於模式匹配,使用時只需要提供record的字段值與給定的字面值都匹配即可,不如給定一輛車,將車的型號為品牌做匹配:

> type car = ;;

type car =

> let matchcar newcars =

-     newcars

-     |> list.filter

-        (function

-             | -> true

-             | -> true

-             | _                -> false);;

val matchcar : car list -> car list

> let cars = [;];;

val cars : car list = [; ]

> matchcar cars;;

val it : car list =

type inference

在f#中,型別推斷系統是乙個非常重要的東西,幾乎所有的地方都需要用到它,現在來看看record是在型別推斷系統下工作的。在.net中,類在使用前,必須標明它的型別,而在f#中,判斷record型別是根據record的字段來的,就像我們上面的說,利用let繫結到乙個大括號包圍的資料,型別推斷系統就能根據它的字段來推理出是record。就拿下面的**段來說,對於值pt1和pt2,沒有任何地方標明它是什麼型別,但是由於x和y值被訪問,並且f#編譯器知道有乙個record包含有欄位x和y,自然就推斷出pt1和pt2的型別了:

> type point = ;;

type point =

> let distane pt1 pt2 =

-     let square x = x * x

-     sqrt <| square (pt1.x - pt2.x) + square (pt1.y - pt2.y);;

val distane : point -> point -> float

> distane ;;

val it : float = 14.14213562

當兩個record的具有相同的字段時,如果像上面這樣寫,那麼型別推斷系統就會發出乙個錯誤了,因為它不知道你希望用到的是哪個型別。為了解決這個問題,你可以提供型別注釋或者完整路徑的字段,比如:

> type point = ;;

type point =

> type vector3 = ;;

type vector3 =

> let distance (pt1 : point) (pt2 : point) =

-     let square x = x * x

-     sqrt <| square (pt1.x - pt2.x) + square (pt1.y - pt2.y);;

val distance : point -> point -> float

引入欄位的完整路徑名可以像下面這樣子:

> let origin = ;;

val origin : point =

methods and properties

在record中也可以增加方法和屬性:

> type vector =

-    

-     member this.length =

-         sqrt <| this.x ** 2.0 + this.y ** 2.0 + this.z ** 2.0;;

type vector =

with

member length : float

end> let v = ;;

val v : vector =

> v.length;;

val it : float = 37.41657387

F 函式式程式設計之 面向鐵道程式設計

原文 參考 不長,先看 吧,我在 後面寫講解。type request let validatename request match request with when name error name must not be blank ok request let validateemail fu...

函式式程式設計之 初窺F

大量講解函式式程式語言的書籍最終都會用fuctor,monad,monoids,範疇論等各種詞彙嚇退命令式語言玩家,所以我試圖避開這些問題,揭開這些複雜詞彙帶來的具有實戰意義的成果。另外我會盡量使用c 語言來描述函式式程式設計思想,因為c 某些語法和特性來自於函式式語言的啟發,但c 終究並不是正統的...

F 函式式程式設計之 隱藏運算

隱藏運算 是我發明的詞,它的正式名稱是 computation expressions 但 computation expressions 這個名稱實在讓人非常費解,也不能反映它的作用,不是乙個好名稱。它的作用是在背後對兩個表示式進行一些操作,讓表示式們表面上看起來簡單。請看例子 let divid...