簡體   English   中英

Curried function 根據自己的部分應用定義

[英]Curried function defined in terms of its own partial application

以下 SML 代碼取自華盛頓大學課程的家庭作業。 (具體來說,它是提供的代碼的一部分,以便學生可以使用它來完成課程網頁上列出的家庭作業 3。)我不是在這里尋求家庭作業幫助——我想我明白代碼在說什么。 我不太明白的是,如何允許根據自己的部分應用來定義咖喱 function。

 datatype pattern = 
     WildcardP
   | VariableP of string
   | UnitP
   | ConstantP of int
   | ConstructorP of string * pattern
   | TupleP of pattern list

fun g f1 f2 p =
  let 
    val r = g f1 f2      (* Why does this not cause an infinite loop? *)
  in
    case p of
        WildcardP         => f1 ()
      | VariableP x       => f2 x
      | ConstructorP(_,p) => r p
      | TupleP ps         => List.foldl (fn (p,i) => (r p) + i) 0 ps
      | _                 => 0
  end

function 綁定是一個遞歸定義,它利用了pattern的數據類型綁定中的遞歸結構。 但是當我們到達val r = g f1 f2 ,為什么這不會導致執行思考,“等等,什么是g f1 f2 f1這就是我通過將f2傳遞給 function 得到的,該g .那么讓我們go回到g的定義“並進入一個無限循環?

function g永遠不會使用f1f2以外的任何值遞歸調用。 按理說g f1 f2不管調用多少次,總會得到相同的結果。

我建議閱讀https://smlhelp.github.io/book/的柯里化部分的暫存部分。

一個更簡單、更簡單的例子,展示了同樣的事情。 一個人為的 function 向下計數一個 int 直到提供的 function 返回 true。

fun x (f: int -> bool) (a: int) : int =
  let 
    val g = x f
  in
    if a = 0 then 0
    else if f a then a
    else g (a - 1)  
  end

我們也可以看到將其轉換為 OCaml 也是如此。

let rec x f a =
  let g = x f in
  if a = 0 then 0
  else if f a then a
  else g (a - 1)

使用 lambda 微積分抽象,咖喱 function gg = (^f1. (^f2. (^p. ...body...)))等等

g a b = (^f1. (^f2. (^p. ...body...))) a      b 
      =       (^f2. (^p. ...body...)) [a/f1] 
      =             (^p. ...body...)  [a/f1] [b/f2]

部分應用程序只生成內部 lambda function 與關閉的兩個參數綁定配對 - 根本不進入正文。

So defining r = g f1 f2 is just as if defining it as the lambda function, r = (^p. g f1 f2 p) (this, again, is LC-based, so doesn't deal with any of the SML-特定的東西,比如類型)。

並且定義一個 lambda function (一個閉包)只是一個恆定時間的操作,它不會進入g function 體,所以更不用說無限循環了。

這些都是等價的,並且都沒有使它看起來可能存在無限遞歸:

您可以用r中的值替換 r,

fun g f1 f2 p =
    case p of
        WildcardP         => f1 ()
      | VariableP x       => f2 x
      | ConstructorP(_,p) => g f1 f2 p
      | TupleP ps         => List.foldl (fn (p,i) => (g f1 f2 p) + i) 0 ps
      | _                 => 0

或“提升”模式匹配,

fun g f1 _ WildCardP = f1 ()
  | g _ f2 (VariableP x) = f2 x
  | g f1 f2 (ConstructorP (_, p)) = g f1 f2 p
  | g f1 f2 (TupleP ps) = List.foldl (fn (p,i) => (g f1 f2 p) + i) 0 ps
  | g _ _ _ = 0 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM