【问题标题】:Fixed Point Generator in C# GenericsC# 泛型中的定点生成器
【发布时间】:2012-01-10 23:03:27
【问题描述】:

我尝试在 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));
}

【问题讨论】:

  • @JaredPar 我还没有尝试用它构建任何函数,只是试图让定义正确。谢谢。
  • @JaredPar Lukazoid 能够帮助我。还是谢谢。

标签: c# haskell functional-programming fixpoint-combinators


【解决方案1】:

我对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);
}

【讨论】:

  • 另请参阅我们以前的同事 Wes Dyer 关于同一主题的帖子:blogs.msdn.com/b/wesdyer/archive/2007/02/02/…
  • @EricLippert 感谢您的链接,我终于花时间来理解这一切
  • 谢谢,在这三种情况下,我似乎有点错了 :) 真正让我困惑的是我试图将 Haskell 语法复制粘贴到 F# 中以查看类型,但 F# 错过了隐含的 x。在 F# 中应该是 'let rec fix f x = f (fix f) x' 非常感谢您的帮助。
  • @AaronStainback: Y 是定点组合器的一个示例,并且是一个非常简单的定点组合器,所以它经常随便说话时被称为“定点组合器”。实际上有无限多的定点组合器,所以说“那个”定点组合器是有误导性的。
  • @EricLippert 感谢您提供这些信息,它清除了很多事情。我试图清理这个问题。
【解决方案2】:

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

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

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

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

fix :: (a -> a) -> a

【讨论】:

  • 我认为这只适用于正常顺序的语言。在像 C#(甚至 ML 系列)这样的应用顺序语言中,Lukazoid 的答案是正确的。
猜你喜欢
  • 2013-04-09
  • 1970-01-01
  • 2016-06-11
  • 2014-11-13
  • 2015-03-14
  • 1970-01-01
  • 2019-04-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多