.net - 选择是否对 F# 中的小型 AST 使用可区分联合或记录类型

标签 .net f# functional-programming record discriminated-union

假设我正在实现一个非常简单的玩具语言解析器。我正在决定是使用 DU 还是记录类型(也许两者混合?)。该语言的结构如下:

a Namespace consists of a name and a list of classes
a Class consists of a name and a list of methods
Method consists of a name, return type and a list of Arguments
Argument consists of a type and a name

使用这种简单语言的程序示例:

namespace ns {
  class cls1 {
    void m1() {}
  }

  class cls2 {
    void m2(int i, string j) {}
  }
}

您将如何对此进行建模?为什么?

最佳答案

您几乎肯定想要使用 DU 来实现交替,其中代码结构的任何部分都可能是多种可能性之一。混合可能是理想的,尽管您可以使用元组代替记录 - 这可能会使使用更简单,但可能更难以阅读和维护,因为元组中没有命名项。

我会把它建模成这样

type CompilationUnit = | Namespace list

and Namespace = { Name : String
                  Body : NamespaceBody }

and NamespaceBody = | Classes of Class list

and Class = { Name : String
              Body : ClassBody }

and ClassBody = | Members of Member list

and Member = | Method of Method

and Method = { Name : String
               Parameters : Parameter list option
               ReturnType : TypeName option
               Body : MethodBody }

and Parameter = { Name : String
                  Type : TypeName }

and MethodBody = ...

and TypeName = ...

使用您的示例语言时,对 DU 的需求可能并不明显,但一旦您在代码中有任何可能是一项或多项的项目,就会变得清楚。举例来说,如果您向类中添加字段 - 您只需向 Member 添加新的 Field 区分即可。

如果您使用语法来解析您的语言(LL/LALR 或类似语言),您可能需要为语法中的每个交替规则匹配一个 DU。

关于.net - 选择是否对 F# 中的小型 AST 使用可区分联合或记录类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7183577/

相关文章:

c# - 在与此域关联的配置文件中找不到部分 'caSTLe'

map - F# - 像对待 map 一样对待函数

C# 列表,在*最后一个非空元素之后删除所有空值

.NET远程速度和VPN

c# - PE32+和PE32有什么区别?

visual-studio - 我应该使用什么开发工具在 F# 中编码?

f# - 简单的rec函数中的F#和内存泄漏

f# - 应该如何将 F# SqlDataConnection TypeProvider 与 App.Config 文件一起使用?

java - 在java中使用lambda获取列表中的值总和

haskell - 函数参数似乎在类型分析中消失了