Генератор с фиксированной точкой в ​​C # Generics - PullRequest
2 голосов
/ 11 января 2012

Я попытался определить генератор с фиксированной точкой в ​​C #, который вы видите во многих функциональных языках. Я полагаю, что foldr обычно определяется в терминах генератора с фиксированной точкой. Я покажу это определение Хаскеля, а затем то, что у меня есть в 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));
}

Ответы [ 2 ]

4 голосов
/ 11 января 2012

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

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

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

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

fix :: (a -> a) -> a
4 голосов
/ 11 января 2012

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

И вот последний метод, который он реализует:

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