2012-01-10 53 views
2

我試圖在C#中定義一個定點生成器,你可以在許多函數式語言中看到它。我相信foldr通常是根據定點生成器來定義的。我將展示它的Haskell定義,然後展示C#中的內容。任何幫助是極大的讚賞。C#泛型中的定點生成器

//Haskell 
fix f = f (fix f) 

//C# (Many attempts) 
public static Func<Func<T, T>, T> Combinator1<T>(this Func<T, T> f) 
{ 
    return x => f(Combinator1(f)(x)); 
} 
public static Func<Func<T, T>, T> Combinator2<T>(this Func<T, T> f) 
{ 
    return x => x(Combinator2(x)(f)); 
} 
public static Func<T, U> Combinator3<T, U>(Func<Func<T, U>, Func<T, U>> f) 
{ 
    return f(x => Combinator3(f)(x)); 
} 
+1

你看到什麼問題? – JaredPar 2012-01-10 23:05:14

+1

@JaredPar我還沒有嘗試過構建任何函數,只是試圖讓定義正確。謝謝。 – 2012-01-10 23:11:50

+0

那麼你在問什麼? – JaredPar 2012-01-10 23:15:58

回答

4

我對haskell或這個操作符沒有太多的理解。但是我已經閱讀了Mads Torgersen關於使用C#lambda表達式實現Y/Fix組合器的文章。它可能對你有些用處,這裏是link

這裏是他實現最後一個方法:

public Func<T, T> Fix<T>(Func<Func<T,T>, Func<T,T>> F) { 
    return t => F(Fix(F))(t); 
} 
+3

另請參閱我們以前的同事韋斯代爾的同一主題的帖子:http://blogs.msdn.com/b/wesdyer/archive/2007/02/02/anonymous-recursion-in-c.aspx – 2012-01-10 23:19:23

+0

@EricLippert感謝您鏈接,我花了最後時間來理解這一切 – Lukazoid 2012-01-10 23:30:17

+0

感謝它看起來像所有三種情況下,我是一個有點錯誤:)真正搞砸了我的是我試圖複製粘貼Haskell語法到F#中看到類型但F#錯過了隱式x。它應該是 在F#中讓我們修復f x = f(修復f)x' 非常感謝您的幫助。 – 2012-01-10 23:41:46

4

首先,的Y組合是無類型演算一個特定的實現。我們更一般地談論定點組合器。

這裏給出的所有答案都很好地顯示了爲什麼定點組合器在沒有捲曲的情況下真的沒有意義。 Lukazoid給出的結果並不像應該那樣普遍。它有這種類型(在Haskell符號):

lukazoidFix :: ((a -> b) -> a -> b) -> a -> b 

一個真正的不動點組合子應該是更加多態。

fix :: (a -> a) -> a 
+0

我認爲這隻適用於正常語言。在像C#這樣的應用程序語言(甚至是ML系列)中,Lukazoid的答案是正確的。 – kvb 2012-01-11 15:34:28