2

我尝试在 C# 中定义一个定点生成器,您可以在许多函数式语言中看到它。我相信 foldr 有时通常是根据定点生成器来定义的。我将展示它的 Haskell 定义,然后展示我在 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));
}
4

2 回答 2

4

我对haskell或this operator的了解不多。但是我读过一篇来自 Mads Torgersen 的关于使用 C# lambda 表达式实现 Y/Fix 组合器的文章。它可能对你有用,这里是链接

这是他实现的最终方法:

public Func<T, T> Fix<T>(Func<Func<T,T>, Func<T,T>> F) {
  return t => F(Fix(F))(t);
}
于 2012-01-10T23:08:09.370 回答
4

首先,Y 组合器是无类型 lambda 演算中的一种特殊实现。我们更一般地谈论定点组合器。

这里给出的所有答案都很好地说明了为什么定点组合器没有柯里化就没有意义。Lukazoid 给出的那个并不像它应该的那样普遍。它有这种类型(在 Haskell 表示法中):

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

一个真正的定点组合器应该是多态的。

fix :: (a -> a) -> a
于 2012-01-11T08:55:49.453 回答