代码之家  ›  专栏  ›  技术社区  ›  WeNeedAnswers

我想在C中看到一些F特性#

f# c#
  •  4
  • WeNeedAnswers  · 技术社区  · 15 年前

    在弄乱了f之后,当我必须回到c时,我想我会错过一些非常好的功能,关于我如何摆脱以下功能的任何线索,或者更好地复制它们的功能:

    • 模式匹配(特别是有差别的联合)
    • 歧视性工会
    • 递归函数(列表的开头和结尾)

    最后,但并非最不重要的是,受Erlang启发的消息处理。

    4 回复  |  直到 6 年前
        1
  •  2
  •   Tomas Petricek    15 年前

    我不确定这到底是个什么程度的问题。然而,这里有一些典型的模式,我用C来编码这些函数结构(其中一些模式来自我的书,它有一个 source code available )

    歧视工会 -在C中实现有区别的联合实际上没有好的方法——您唯一能做的就是将它们实现为类层次结构(其中一个基类表示du类型,每个du案例都有一个派生类)。您也可以添加 Tag (某些)财产 enum 输入)到基类,以便更容易地检查该类表示的情况。据我所知,它被用于LINQ表达式树(实际上应该区分联合)。

    模式匹配 -您可能永远不会以一种完全通用的方式(例如,使用嵌套模式)得到这个结果,但是您可以在这样的有区别的联合上模拟模式匹配(使用 Option<int> 类型为 Some of int None ):

    Option<int> value = GetOption();
    int val;
    if (value.TryMatchSome(out val)) 
      Console.WriteLine("Some {0}", val);
    else if (value.TryMatchNone()) 
      Console.WriteLine("None");
    

    不完美,但至少你能找到一种从案例中提取值的相对好的方法。

    消息传递 -有 Concurrency and Coordination Runtime ,在某些方面也基于消息传递,可以在C中使用。我打赌您也可以使用C中的F邮箱处理器,使用基于迭代器的技术,我在 this article 也用于Wintelect PowerThreading库。但是,我认为没有人基于这个想法实现了一个可靠的消息传递库。

    总之,您可以在C中模拟许多功能特性,至少在某种程度上进行了扩展,并使用一些其他功能而没有任何问题(lambda函数和高阶函数)。然而,如果你需要f的全部力量,那么你只需要说服你的公司开始使用f:-)。

        2
  •  7
  •   Reed Copsey    15 年前

    使用 F# to make reusable libraries you can call from C# .

    关于F一个非常好的地方是它仍然是一种.NET语言。您可以在clr中任意混合和匹配语言…

        3
  •  2
  •   Community CDub    8 年前

    虽然类型定义有点冗长(请参见 How can I duplicate the F# discriminated union type in C#? 为了一些想法)。这是我在这个问题上提倡的方法:F型 type T = ACase of A | BCase of B | CCase of C 可以用一个带有一些静态助手方法的抽象类来表示。

    public abstract class T {
        public abstract X Match<X>(Func<A,X> aCase, Func<B,X> bCase, Func<C,X> cCase);
    
        private class ACase : T {
            private A a;
            public ACase(A a) { this.a = a; }
    
            public override X Match<X>(Func<A,X> aCase, Func<B,X> bCase, Func<C,X> cCase) {
                return aCase(a);
            }
        }
        private class BCase : T {
            private B b;
            public BCase(B b) { this.b = b; }
    
            public override X Match<X>(Func<A,X> aCase, Func<B,X> bCase, Func<C,X> cCase) {
                return bCase(b);
            }
        }
        private class CCase : T {
            private C c;
            public CCase(C c) { this.c = c; }
    
            public override X Match<X>(Func<A,X> aCase, Func<B,X> bCase, Func<C,X> cCase) {
                return cCase(c);
            }
        }
    
        public static T MakeACase(A a) { return new ACase(a); }
        public static T MakeBCase(B b) { return new BCase(b); }
        public static T MakeCCase(C c) { return new CCase(c); }
    }
    

    匹配现在看起来类似于f,但没有大小写标签。相当于此F代码:

    function
    | A a -> 1
    | B b -> 2
    | C c -> 3
    

    这是C代码吗?

    public static int MatchDemo(T t) {
        return t.Match(
            a => 1,
            b => 2,
            c => 3);
    }
    
        4
  •  0
  •   Community CDub    8 年前

    退房

    switch / pattern matching idea

    以一些疯狂的方式尝试在C中进行模式匹配。