6 4 3 分步分析(Evaluating)示例

2021-06-26 17:44:31 字數 1939 閱讀 6777

6.4.3 分步分析(evaluating)示例

能這像這樣自信地使用高階函式,是需要一些時間的,尤其是巢狀使用。我們將研究前面清單中的**的地,通過跟蹤幾個樣本輸入。從抽象的問題「一般情況下這段**做什麼?」,到具體的問題「特定情況下這段**做什麼?」,通常可以幫助澄清真相。

如果我們第一次輸入乙個無效的值,會發生什麼。那時,從 readinput() 返回的第乙個值將是 none。要看到會發生什麼,我們使用計算(computation by calculation),可以展示程式是如何一步一步進行計算(evaluates)的。在清單 6.12 中可以看到計算的過程。

清單 6.12 第乙個輸入無效時的分析

首先,分析 readandadd2 的函式體:

readinput() |> option.bind (fun num–>

readinput()|> option.map ((+) num) )

讀取使用者的第乙個輸入,然後,用返回的 none 替換 readinput() 呼叫:

none |> option.bind (fun num –>

readinput()|> option.map ((+) num) )

再分析 option.bind 呼叫。lambda 函式沒有被呼叫,因此,整體返回結果是:

none

在第一步,我們用 none 替換函式呼叫,這是在輸入無效數字(例如,空字串)時,函式的返回值;第二步更加重要,這裡,none 作為option.bind 函式的第二個引數值。然而,none 並不包含任何數,因此,bind 不會呼叫指定的 lambda 函式,只會做一件事,就是立即返回 none。

現在,如果第乙個輸入為 20 時,函式的行為又是怎樣呢?很明顯,會有兩種情況:一是第二個輸入正確,另乙個是輸入無效。清單 6.13 顯示了第二個輸入為 22 時的行為。

清單 6.13 分析兩個輸入都有效的情況

首先,分析 readandadd2 的函式體:

readinput() |> option.bind (fun num–>

readinput()|> option.map ((+) num) )

讀取使用者的第乙個輸入,然後,用第乙個輸入代替 readinput() 呼叫。這裡,它包含了值:

some(20) |> option.bind (fun num –>

readinput()|> option.map ((+) num) )

分析 option.bind call 呼叫。它呼叫 lambda 函式,並把 20 作為引數值。在**中,我們用實際值替換所有的 num:

readinput() |> option.map ((+) 20)  [1]

再讀取使用者的第二個輸入。讀取第二個輸入值

some(22) |> option.map ((+) 20)

some( (+) 20 22 )    [2]

最後,分析 + 運算子。計算 20 + 22,結果仍打包在 some 分支下:

some(42)

第一步是類似於前一種的情況,但這次,我們用some(20) 作為引數值呼叫 option.bind,這個選項值包含數字,可以作為引數值,傳遞給提供的 lambda 函式的num 引數。option.bind 返回從這個函式得到的結果,因此,下一步的結果將是這個函式體[1]。我們還用實際值 20,替換了所有的 num。

然後,我們用 readinput() 讀第乙個輸入值,返回 some(22)。用 some(22) 替換 readinput(),我們可以分析 option.map 函式。這個函式把它作為引數值,另外,把結果打包在 some 識別器中。因此,下一步顯示[2],需要下一步計算加法,並將結果打包在 some 中。計算加法之後,最後得到的結果是:some(42)。

跟著分步解釋,我們應該對 option.bind 和 option.map 是如何工作的,有了相當好的理解。有了這方面的知道準備,我們就可以看一下如何在 f# 和 c# 中,實現這兩種操作了。

poj2479分步DP精簡成O n 演算法

提取資訊包括從s到t之間的和 但是n較大這樣dp i j 的形式顯然不行,那麼如果轉換 其實我們除了記錄 i,j 之間的和那麼可以記錄以i開頭和以i結尾兩種情況 後來發現根本不用記錄以什麼為開頭或者結尾,每次更新前面一段值就行 725k 438ms include using namespace s...

分目錄 分埠

分目錄站點 意義 可能有多個cms或框架組成,對於滲透 相當於滲透目標是多個 入侵分目錄下的站點 主站也跟著被入侵 主站與分目錄站點搭建的cms可能不同 找到乙個有漏洞可利用的cms即可對 進行入侵 分埠站點 同理 www.com www.com 8080 www.com 8888 意義 可能有多個...

luoguP4231 三步必殺 差分

luogup4231 三步必殺 差分 題意 n 個柱子排成一排,一開始每個柱子損傷度為0。接下來勇儀會進行m次攻擊,每次攻擊可以用4個引數l,r,s,e來描述 表示這次攻擊作用範圍為第l個到第r個之間所有的柱子 包含l,r 對第乙個柱子的傷害為s,對最後乙個柱子的傷害為e。攻擊產生的傷害值是乙個等差...