首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >F#对C#对Nemerle

F#对C#对Nemerle
EN

Stack Overflow用户
提问于 2010-12-30 09:37:21
回答 8查看 6K关注 0票数 35

在我的TODO中有了新的项目,不能选择F#或Nemerle。

我目前正在学习F#,并在Nemerle上有一些项目。

我喜欢F#方式,默认情况下我喜欢缩进(默认情况下我也想缩进nemerle2),我喜欢F#的许多特性和魔力,但是没有宏。

F#的目标是VS2010,也许是更大的开发团队,它看起来像Haskell(可以用它创建轻松的Linux程序,而且很有趣)。

Nemerle的目标是宏,我想我更喜欢Nemerle的一些语法。

大多数人都喜欢C#..。

  • 所以语言必须是透视的
  • 语法必须符合逻辑,易于理解,整洁有力(代码少)
  • 它必须易于与.NET一起使用
  • 因此,我已经关闭了我自己的选择,这三个。
  • 我可以全部使用,但选择一个怎么样?对我来说可不容易。

举个例子,我喜欢(内梅勒)

代码语言:javascript
复制
match(STT)
    | 1 with st= "Summ"
    | 2 with st= "AVG" =>
        $"$st : $(summbycol(counter,STT))"

远不止此(F#)

代码语言:javascript
复制
let (|Let|) v e = (v, e)

match stt with 
| Let "Summ" (st, 1) 
| Let "AVG" (st, 2) -> srintf "%s ..." st

F#:

代码语言:javascript
复制
["A"; "B"] |> List.iter (fun s  -> printfn "%d"  s.Length)

内梅勒:

代码语言:javascript
复制
["A", "B"].Iter(x => printf("%d", x.Length))

F# (希望这里没有弄错):

代码语言:javascript
复制
let type X =
    let mytable a = ""
    let mytable b = ""
    new(A, B) = {
    a <- A
    b <- B }
    member X.A 
        with get  = a
    member X.B 
        with get  = a

内梅勒:

代码语言:javascript
复制
[Record]
class X
  public A : string { get; }
  public B : string { get; }

C#:

代码语言:javascript
复制
class X
{
    private readonly string _a;
    public string A { get { return _a; } }

    private readonly string _b;
    public string B { get { return _b; } }

    public X(string a, string b)
    {
        _a = a;
        _b = b;
    }
}

下面是我已经无法转换成F#的nemerle代码(所以我只是学习它).

代码语言:javascript
复制
abstract class ABase
    abstract public A : string { get; }

interface IB
    B : string { get; }

[Record]
class My : ABase, IB
    public override A : string { get; }
    public virtual  B : string { get; }

与C#的比较:

代码语言:javascript
复制
abstract class ABase
{
    abstract public string A { get; }
}

interface IB
{
    string B { get; }
}

class My : ABase, IB
{
    private readonly string _a;
    public override A : string { get { return _a; } }

    private readonly string _b;
    public virtual  B : string { get { return _b; } }

    public My(string a, string b)
    {
        _a = a;
        _b = b;
    }
}

显然,Nemerle代码更易于支持和更易读。

@Brian --这就是我为什么要问的原因,让我看看这是否真实,让这个用户在F#上更容易理解,C#,如果你看到我做错了,因为我不确定是否有其他方法可以清楚地表达相同的观点。

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2010-12-30 11:08:24

F#和Nemerle版本完全不同:

  1. Nemerle定义类,而F#定义结构。
  2. Nemerle定义只读成员,而F#定义可变成员。
  3. Nemerle定义公共属性,而F#定义公共字段。
  4. Nemerle定义构造函数,而F#没有定义构造函数。

F#示例的类似Nemerle代码如下所示:

代码语言:javascript
复制
struct X
  mutable A : string
  mutable B : string

第二个例子几乎相同:

  1. Nemerle为My F#未定义构造函数定义构造函数。
  2. Nemerle定义属性,它返回在构造函数中传递的值,而F#用常量值定义属性。

Nemerle版本比这里的F#版本更短、更清晰。

关于大括号和缩进语法。Nemerle支持这两种语法。

你可以写:

代码语言:javascript
复制
class M
{
  static Main() : void
  {
    Console.WriteLine("A");
  }
}

或使用缩进:

代码语言:javascript
复制
#pragma indent
class M
  static Main() : void
      Console.WriteLine("A");

甚至使用这两种样式!

代码语言:javascript
复制
#pragma indent
class M
  static Main() : void { Console.WriteLine("A"); }
票数 12
EN

Stack Overflow用户

发布于 2011-01-03 19:19:56

告诉我,如果这是真实的,使这个容易在F#,C#,如果你看到我做错了,因为我不确定其他方式清楚地使同样的。

您的F#和C#示例不太简洁。让我们重写OP中的一些示例:

模式匹配

内梅勒:

代码语言:javascript
复制
match(STT)
    | 1 with st= "Summ"
    | 2 with st= "AVG" =>
        $"$st : $(summbycol(counter,STT))"

F#:

我不能百分之百确定你的代码在做什么,但是它看起来是基于这个答案的。我不认为在匹配表达式中创建新变量很容易,但我认为活动模式太过分了。

我会像这样写代码:

代码语言:javascript
复制
let st = match stt with 1 -> "Summ" | 2 -> "Avg"
sprintf "%s ..." st

地图也起作用:

代码语言:javascript
复制
let sttMap = [1, "Summ"; 2, "Avg"] |> Map.ofList
sprintf "%s ..." (sttMap.[stt])

我也是<3 乔恩的建议

代码语言:javascript
复制
let 1, st, _ | 2, _, st = stt, "Summ", "AVG"

记录

内梅勒:

代码语言:javascript
复制
[Record]
class X
  public A : string { get; }
  public B : string { get; }

F#:

代码语言:javascript
复制
type X = { A : string; B : string }

C#:

代码语言:javascript
复制
class X {
    public string A { get; private set; }
    public string B { get; private set; }

    public X(string a, string b) {
        A = a;
        B = b;
    }
}

内梅勒

代码语言:javascript
复制
abstract class ABase
    abstract public A : string { get; }

interface IB
    B : string { get; }

[Record]
class My : ABase, IB
    public override A : string { get; }
    public virtual  B : string { get; }

F#:

代码语言:javascript
复制
[<AbstractClass>]
type ABase() =
    abstract member A : string

type IB =
    abstract member B : string

type My(a, b) =
    inherit ABase()
    override this.A = a

    abstract member B : string
    default this.B = b
    interface IB with
        member this.B = this.B

这里要注意的是:

  • F#接口是使用abstract关键字定义的。可以使用[<AbstractClass>]属性将它们转换为抽象类。
  • 接口是显式实现的。通常,您需要将对象转换为接口定义来调用接口成员:let x = My("a", "b"); printf "%s" (x :> IB).B。为了避免强制转换,您需要创建反映您的接口方法的公共成员。
  • 虚拟函数定义带有abstract member实现的default

将所有这些组件组合在一起,就可以得到对眼部神经有害的类定义。但这是可以的,因为类通常不是经常使用的。大多数F#对象模型都是通过联合和记录来定义的;在使用类的地方,类层次结构是非常平坦的,而不是很深的,因此您看不到继承或虚拟函数在F#中使用的频率比C#高。

C#:

代码语言:javascript
复制
abstract class ABase {
    public abstract string A { get; }
}

interface IB {
    string B { get; }
}

class My : ABase, IB {
    public override string A { get; private set; }
    public virtual string B { get; private set; }

    public My(string a, string b) {
        A = a;
        B = b;
    }
}

长话短说,我认为F#与Nemerle相当,但看起来你只是在学习它。别担心,当我学习F#时,我正在编写丑陋的、笨重的代码,这些代码基本上是用更时髦的语法反映C#的。花了一小段时间我才能写得更有成语。

我建议如下:

  • 如果您熟悉Nemerle并喜欢使用它,请继续这样做:)
  • 如果你想学习F#,我认为你的项目是一个很好的起点。我认为你可以把F#写成干净或者比你的记忆更好。
  • C#也可以,但是如果您正在进行大量的模式匹配或符号处理,我不喜欢这两种语言。
票数 15
EN

Stack Overflow用户

发布于 2010-12-30 15:19:35

F#记录的语法是

代码语言:javascript
复制
type X = { 
    A : string
    B : string 
}

至于你不能转换的代码

代码语言:javascript
复制
[<AbstractClass>]
type ABase() =
    abstract A : string

type IB = 
    abstract B : string

type MyClass(a, b) = 
    inherit ABase()
        override this.A = a
    interface IB with 
        member this.B = b

我不太确定您的模式匹配示例要做什么,但是F#有语法(我认为您正在寻找)

代码语言:javascript
复制
match (STT) with
    | 1 when st = "Sum" -> ...
    | 2 when st = "Avg" -> ...
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4561524

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档