函式值和簡單值

2022-05-23 08:03:12 字數 2834 閱讀 5915

不分配繫結

我們再來看一下這個簡單的函式:

let add1 x = x + 1
"x"是什麼意思呢?"x"意思是:

1:從輸入值域中接收一些值

2:我們可以先用名字為「x」來表示值,以便之後引用它。

用名字表示值得過程稱為"繫結(binding)",這個"x"是輸入值的"確定值"。

如果我們以5為輸入值計算這個函式,我們將會把原定義中看到的「x」替換為「5」,某種程度上這很像在文字上的查詢替換。

let add1 x = x + 1

add1 5//

replace "x" with "5"

//add1 5 = 5 + 1 = 6

//result is 6

明白這不是分配非常重要。"x「不是乙個「插槽」或變數只是分配值給它,而且可以在以後分配另乙個值給它。這只是名稱「x」和值得一次性關聯。這個值是已經定義的值,不能改變。而且,一旦確定,「x」也不能改變。一次關聯乙個值,總是關聯乙個值。

函式化思維中乙個重要的觀點:沒有變數,只有值。

如果你思考得多一點,你會發現 名字為「add1」的本身,繫結給"輸入值加一的函式"。函式本身是獨立於它繫結到的名稱的。

如果你輸入"let add1 x=x+1",你是告訴f#編譯器,當他看到add1的時候,就會用給輸入加一的函式代替它。「add1」稱為函式值。

為了了解函式是獨立於它的名字,試一下:

let add1 x = x + 1

letplus1 = add1

add1

5plus1

5

你可以看到」add1「和」plus1「引用(繫結)同樣的函式。

你總是可以認出乙個函式,因為他們有標準的簽名」domain->range「。下邊是乙個函式值的泛型:

val functionname : domain -> range
想想乙個沒有輸入總是返回整數5的操作

這是乙個」常量「操作 。

在f#中怎麼寫呢?我們會告訴f#編譯器,每次看到名字」c「,就會整數5替換它。

let c = 5
當它執行,返回:

val c : int = 5
這次沒有箭頭對映,只是乙個整數。不一樣的是列印實際值後有乙個等號。f#編譯器知道這個繫結總是返回乙個值即5.

換句話說,我們定義了乙個常量,在f#中是簡單值。

你總是可以區分函式值和簡單值,因為所有的簡單值都有像這樣的簽名:

val aname: type = constant     //

note that there is no arrow

與c#不同,在f#中重要的是函式值和簡單值是有一點不同的。他們都可以用名字來繫結(用let關鍵字)和傳遞。事實上,函式化程式設計的關鍵面之一是函式可以作為其他函式的輸入值

,我們很快就可以看到。

注意函式值和簡單值微妙的不同。乙個函式總是有乙個域和乙個範圍,必須提供乙個引數得到乙個結果。乙個簡單值確定之後就不需要再計算。由於它們的不同,我們不得不這樣去定義乙個返回5的"常量函式"。

let c = fun()->5

//or

let c() = 5

這些函式的簽名是:

val c : unit -> int
而不是這樣:

val c : int = 5
之後更多unit ,函式語法和匿名函式。

在像f#這種函式式程式語言中,很多東西都叫做"值"。在像c#這樣的物件導向語言中,很多東西都叫做"物件".那麼他們之間有什麼不同嗎?

我們已經在前邊知道,值只是域中的成員。整數域,字串域,函式域,從整數到字串的對映等等。原則上,值是不能改變的。而且值沒有任何附加的行為。

物件,標準的定義是帶有相關行為(方法)的資料結構的封裝。總的來說,物件是有狀態的(可以改變),所有改變內部的操作都必須由物件自己提供(用"."符號)。

在f#中,也有基元型別有類似物件的行為,例如,你可用"."出來獲取字串的長度。

"

abc".length

但是,總的來說,我們應該避免為標準值使用"物件",保留它是因為真實類的例項或者暴漏成員方法的其他值。

值和函式名的標準命名規則,基本上,任何字母字串,包括下劃線。有幾個額外的:

你可以在名字用單引號,除了不能放在第乙個位置,其他都可以。例如:

a'

b'c begin

'// valid names

最後的單引號通常是用來發出值的某種」變種」版本的標誌:

let

f = x

let f'

= derivative f

let f'' = derivative f'

或者定義關鍵字的變形:

letif'

b t f = if b then t else f

你可以在任何字串使用雙引號使它成為有效識別符號。

``this is a name``  ``123``    //

valid names

你可能想使用雙引號識別符號的時候

不像c#,f#的函式和值得命名約定,首字母以小寫開始而不是大寫(駱駝命名而不是帕斯卡命名),除非專為暴露於其他.net語言。可是型別和模組用首字母大寫形式。

翻譯有誤,請指正,謝謝!

翻譯目錄傳送門:

5 5 2 1 函式作為引數值和返回值

5.5.2.1 函式作為引數值和返回值 在第三章,我們已使用過,在 c 和 f 中把函式作為引數值,因此,這些基本概念不應該是新的 然而,我們還沒有以這種方式使用過 lambda 函式。lambda 函式是把函式寫成另外函式的引數值的最簡單方法。清單 5.17 提供了乙個簡單的示例。在清單中前面的函...

hermite插值 數值計算筆記2 函式插值逼近

給出經過樣本點的連續函式。n 1個點對應n次多項式,盡量用內插發,並且選用已知節點使插值節點與公式中的已知節點近一些。1.lagrange差值問題的解函式是存在唯一的 2.lagrange 插值多項式 3.一般的newton插值多項式 先寫出差商表 3.等距節點的newton插值多項式 先寫出差分表...

C 結構體作為函式引數 值和引用 和返回值

我們在前面的一些章節中知道,變數作為函式的引數,了解它是值傳遞還是位址傳遞是非常重要的。因為這意味著引數在函式體內的修改是否會影響到該變數本身。不同於陣列,結構是按值傳遞的。也就是說整個結構的內容都複製給了形參,即使某些成員資料是乙個陣列。下面,我們就以乙個例項來證明這一點 程式9.3.1 incl...