2012-01-10 3 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

+1

@ JaredPar Я еще не пробовал строить с ним какие-либо функции, просто пытался правильно определить определение. Благодарю. –

+0

Итак, что же вы спрашиваете? – JaredPar

ответ

4

У меня нет большого понимания haskell или этого оператора. Но я прочитал статью от Mads Torgersen о внедрении комбинатора Y/Fix с использованием выражений лямбда C#. Это может быть вам полезно, вот 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 –

+0

@EricLippert Спасибо за ссылка, я беру время, наконец, чтобы понять все это – Lukazoid

+0

Спасибо, похоже, что во всех трех случаях я был несколько неправильным :) Что действительно испортило меня, я попытался скопировать вставку синтаксиса Haskell в F # см. типы, но F # пропустил неявный x. это должно было быть 'let rec fix f x = f (fix f) x' в F # Большое спасибо за вашу помощь. –

4

Прежде всего, Y-Combinator является конкретной реализацией в нетипизированном лямбда-исчислении. Мы говорим в основном о комбинаторах с фиксированной точкой.

Все приведенные здесь ответы прекрасно показывают, почему комбинаторы с фиксированной точкой действительно не имеют смысла без каррирования. Тот, который дается Лукасоидом, не так важен, как должен. Он имеет следующий вид (в Haskell нотации):

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

Реальная точка комбинатор фиксированной должна быть намного более полиморфными.

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

Я думаю, что работает только на обычном языке. В языке аппликативного порядка, таком как C# (или даже семейство ML), ответ Лукасоида правильный. – kvb