2016-01-02 42 views
1

在swift中,是否有可能接受另一個與它自己類型相同的函數?我怎樣纔能有一個函數接受同一類型的函數?

例如,我在python這個功能: lambda f: f(f)

我怎樣才能在迅速確定這樣的功能? f的類型是什麼?

+0

我不認爲這是可能的。對於任何類型'A','A - > Void'或'A - > B'是不同的類型。 –

+0

請在'python'中給我們一些具體的使用例子。 'lambda f:f(f)'有點模糊。 – Cristik

回答

3

從你的問題聽起來就好像你正在尋找一種方式來定義self-application combinator (/U combinator)。我不確定是否可以在Swift中實現U combinator行爲,但是,您可以深入瞭解相關的fix-point combinator (/Y combinator)和遞歸關閉。


可以通過定義一個函數,它一個功能起作用高階函數作爲參數,說f: (T->U) -> (T->U),並返回相同類型的功能,即(T->U)實現Y組合的行爲。使用這種方法,您的功能可以從本身作爲參數獲取等功能。

短的版本是,Y組合計算的 功能定點 - 消耗(在這種情況下,會產生)的函數的 另一功能。

訣竅是將遞歸函數定義爲 非遞歸函數的固定點,然後編寫一個定點查找程序--YY組合器 - 而不使用遞歸。

http://matt.might.net/articles/js-church/

現在,既然你返回一個函數在兩個步驟,你的回報將是「嵌套」;外界定義了封閉的返回,而內部則定義了類型的返回。關鍵是內在的,遞歸的,回報;你可以在其中調用輸入(參數)函數本身而不顯式地使用它的名字:你可以使用函數參數---如上所述---構造成一個可以容納函數本身的閉包類型。

func myCombinator<T,U>(f: (T->U) -> (T->U)) -> (T->U) { 
    return { 
     (x: T) -> U in 
     return f(myCombinator(f))(x) 
    } 
} 

使用此功能,你可以,例如,計算一個數的階乘沒有功能明確提及自己的名字

func factorialHelper(recursion: Int -> Int)(n: Int) -> Int { 
    switch n { 
    case 0: return 1 
    default: return n * recursion(n-1) 
    } 
} 

let factorial = myCombinator(factorialHelper) 
print("\(factorial(4))") // 24 

有關Y組合的參考和遞歸倒閉的背景下斯威夫特,見例如

這是從上方在該回答的示例中所採取的第二參考。


不久返回到U組合子,有一個簡單的「天然的」迅速情況下(但是,相當無用),該至少模擬形式lambda f: f(f)

考慮一個void函數,比如說f,將一個空元組類型作爲單個函數參數。空元組()是一種類型(typealias Void指類型())以及該類型的單個值。由於f是無效的(沒有顯式返回),它隱含地返回一個空元組()作爲一個值。

因此---雖然沒有真正涉及到U組合子---你可以寫類似

func f(_:()) { } 
var lambda_f = f(f()) 

lambda_f = f(f(f())) 
+0

必須myCombinator是否顯式遞歸? –

相關問題