4

我已經開始理解一些與柯里有關的示例,但我仍然不喜歡柯里化的概念,因爲我想成爲。我知道咖喱可以用來做部分評估,但我不確定它在某些情況下會如何工作。部分評估和柯魯格

我知道它是如何工作在下面的例子:

fun funkyPlus x y = x*x+y; 

所以我們說,我們只能通過對X的參數,那麼它等同於以下內容:

fun funkyPlus 3 = (fn x => fn y => x*x+y)3 

這最終返回

fn y => 9+y 

現在,我試圖將這個想法應用於內置函數foldl

我知道它的代碼是:

fun foldl f b [] = b 
    |foldl f b (h::t) = foldl f f(h,b) t. 

我的問題是,如果我們沒有所有的參數傳遞給foldl(即我們只把它傳遞是函數('a*'b->'b)的第一個參數)。在我給出的第一個例子中,當只有一個參數傳遞給它時,看看函數是如何工作的非常簡單。但是,如果只有一個參數傳遞給它,foldl將無法​​工作。

幫助。

+3

部分*申請*。 – 2011-02-12 01:46:57

回答

2
  1. 這並不意味着你在想什麼:

    fun funkyPlus 3 = (fn x => fn y => x*x*y)3 
    

    它定義一個函數,該函數必須是3的參數,並計算其RHS如果是3,是不確定的,否則。你的意思是說:如果我們只提供x的一個參數,我們有以下內容:

    funkyPlus 3 
    → (fn x => fn y => x*x+y) 3 
    

    等等。

  2. 其次,有一個在您foldl錯誤:

    fun foldl f b [] = b|foldl f b (h::t) = foldl f f(h,b) t; 
                   ^^^^^ 
    Type clash: expression of type 
        'a * 'b 
    cannot have type 
        'c list 
    

    這是因爲(h,b)被解析爲第三個參數foldl而不是作爲參數傳遞給f。圓括號它:

    fun foldl f b [] = b|foldl f b (h::t) = foldl f (f(h,b)) t; 
    > val ('a, 'b) foldl = fn : ('a * 'b -> 'b) -> 'b -> 'a list -> 'b 
    

現在,讓你的問題,ML可以告訴我們,像foldl add表達將有類型int -> int list -> int

但是總的來說,它可能有助於認識到功能應用是完全機械的。如果我們有兩個定義:

fun foldl f b [] = b 
    | foldl f b (h::t) = foldl f (f(h,b)) t; 
add (x,y) = x + y; 

然後var example = foldl add將是相同的:

fun example b [] = b 
    | example b (h::t) = example (h::t) (add(h,b)) t; 

所有這一切已經做的是add已在foldl身體被取代f,僅此而已(儘管我冒昧在體內替換foldl addexample)。

1

的第一步是把方程foldl的頂層設置成採用情況下分析,像這樣的λ表達式:

val rec foldl = fn f => fn b => fn lst => 
    case lst of [] => b 
     | (h::t) => foldl f (f(h,b)) t 

現在可以像以前一樣使用相同的邏輯。以作爲一個例子的功能fn (x, y) => x * y,我們可以看到,

val prod = foldl (fn (x, y) => x * y) 

相當於

val prod = (fn f => fn b => fn lst => 
    case lst of [] => b 
     | (h::t) => foldl f (f(h,b)) t) (fn (x, y) => x * y) 

其中beta-reduces

val prod = fn b => fn lst => 
    case lst of [] => b 
     | (h::t) => foldl (fn (x, y) => x * y) ((fn (x, y) => x * y)(h,b)) t 

其中β-內減少到

val prod = fn b => fn lst => 
    case lst of [] => b 
     | (h::t) => foldl (fn (x, y) => x * y) (h * b) t 

現在,因爲我們從第一個定義知道prod相當於foldl (fn (x, y) => x * y),我們可以代入自己的定義:

val rec prod = fn b => fn lst => 
    case lst of [] => b 
     | (h::t) => prod (h * b) t 

然後,我們可以精神上轉換這回由公式定義的函數,如果我們喜歡:

fun prod b [] = b 
    | prod b (h::t) = prod (h * b) t 

這是關於你期望的,對嗎?

+0

+1,用於實際顯示步驟。 – 2011-02-12 02:58:31