2015-10-21 72 views
1

我目前正在學習OCaml,我想到了這段代碼。函數關鍵字的區別以及在OCaml中的匹配

let rec tree_to_list acc = function 
    | Leaf x -> x::acc 
    | Node (t1,t2) -> tree_to_list (tree_to_list acc t2) t1 

據我理解這個功能做了同樣的比這個

let rec tree_to_list2 acc t = match t with 
    | Leaf x -> x::acc 
    | Node (t1, t2) -> tree_to_list t1 (tree_to_list2 acc t2) 

不過,我不明白的第一個函數後面的語法。我發現關鍵字功能令人困惑。它應該是一個參數只如:

function x -> x + 2 

可能有人請幫助我理解第一個函數的語法,如果任何在這兩者的功能是如何評估方面的差異。提前致謝。

+0

是的,有點令人困惑,我們有3個函數定義語法,並在參數綁定方面模式匹配 - 是的,你可以模式匹配左等號。 –

+0

Colin G.D.在OCaml中有一篇關於函數式編程的簡介(www.france-universite-numerique-mooc.fr)。它仍然是開放的。他本週開始(由Xavier Leroy介紹)。 –

+0

嗨@ V.Michel我知道這個mooc,我的老師是背後的老師,不過謝謝你。 –

回答

2

OCaml中的函數是通過爲參數提供模式來定義的。簡單變量名稱的常見情況(如第一個函數中的acc)只是與所有值匹配的特定類型的模式。

所以,一種看待它的方法是fun定義了一個函數,它具有任意數量的參數,每個參數可以由一個模式給出。另一方面,function定義了一個函數,其中一個參數可以由任意數量的模式給出。

# let dot = fun (a, b) (c, d) -> a *. c +. b *. d 
val dot : float * float -> float * float -> float = <fun> 

# let geti = function None -> 0 | Some i -> i;; 
val geti : int option -> int = <fun> 

fun形式可以在本質上被吸收到一個let的左手側,以提供更簡潔的表示法。

即,

let f = fun p1 p2 -> ... 

可以寫成

let f p1 p2 = ... 

因此,例如:

let dot (a, b) (c, d) = a *. c +. b *. d 

你的第一函數使用兩個(一簡要fun的組合和右邊的function)。

0

第一個函數只是不明確地命名它的參數。 你可以做同樣的,增加了2功能:

let f = (+) 2;; 

這將增加2至任何數量和ARG沒有明確命名。

3

據我理解這個功能確實比這個

你是在正確的兩段代碼進行評估一樣一樣的。

可能有人請幫助我理解第一功能

的語法@JeffreyScofield似乎已經非常漂亮地回答了這個部分,我將重點放在第二部分。

如果在兩者的功能如何被評估

對TL方面的任何差異; dr爲沒有差別和所產生的組件實際上是相同的。我們將使用一個簡單的斐波那契示例來顯示使用match withfunction表示法發射的組件。

let rec fib n = match n with 
| 0 -> 0 
| 1 -> 1 
| i -> fib (i - 1) + fib (i - 2) 

let rec fib = function 
| 0 -> 0 
| 1 -> 1 
| i -> fib (i - 1) + fib (i - 2) 

都產生

fib: 
    subq $24, %rsp 
.L102: 
    cmpq $1, %rax 
    je .L100 
    cmpq $3, %rax 
    je .L101 
    movq %rax, 0(%rsp) 
    addq $-4, %rax 
    call fib 
.L103: 
    movq %rax, 8(%rsp) 
    movq 0(%rsp), %rax 
    addq $-2, %rax 
    call fib 
.L104: 
    movq 8(%rsp), %rbx 
    addq %rbx, %rax 
    decq %rax 
    addq $24, %rsp 
    ret 
.L101: 
    movq $3, %rax 
    addq $24, %rsp 
    ret 
.L100: 
    movq $1, %rax 
    addq $24, %rsp 
    ret 

注:我故意除去.align S和這樣。

要驗證要求,這些產生相同的組件(並因此評估相同的),則可以簡單地把各功能在一個文件中,然後運行

$ ocamlopt -S fib-with-match.ml 
$ ocamlopt -S fib-with-function.ml 

diff兩個,則應該看到它與無差異返回:

$ diff fib-with-match.s fib-with-function.s 
$ 

這是非常常見的有僅包含OCaml中match表情功能,從而@JeffreyScofield說,function具有可用於模式MA參數tching。因此,它是有效的語法糖。

來源:

1

我的方式來解釋OCaml中的函數定義:

這些等價的:

let name p1 p2 ... pn = expr 
let name = function p1 -> function p2 -> ... -> function pn -> expr 
let name = fun p1 p2 ... pn -> expr 

如何備忘錄RIZE它:

  • 首先是語法糖,

  • 第二個是它真正的內部呢,

  • 三是從傳統的CAML。

現在function只有一個參數,但它常常被這樣的 - 這些都是等同,你在P3匹配:

let f1 p1 p2 p3 = match p3 with 
| [] -> expr 
| ... 

let f2 p1 p2 = function 
    | [] -> expr 
    | ... 

你看到的第二個版本可以節省一些源字符,消除視覺混亂。或者更多:不需要將值綁定到p3而不使用p3變量,因爲模式匹配是最好的綁定構造。