如何在OCaml变体中命名字段?

  • 本文关键字:字段 OCaml ocaml variant
  • 更新时间 :
  • 英文 :


包含大量字段的变量开始变得笨拙。每个字段的作用以注释结束:

type ty =
| FunTy of (*all*) ty list * (*params*) ty list * (*return type*) ty
...

一个解决方案是让变量的值是一个记录。

type ty =
| FunTy of ft
...
and ft = {
forall : ty list;
p_tys : ty list;
ret_ty : ty
}

但是,需要间接地取消对记录字段的引用。这与我的目的无关,但我可以看到这种性能差异使上述重构在实践中变得独特。

为了保持答案的客观性,参考OCaml文档或风格指南会有所帮助。

自OCaml 4.03(2016年发布)以来,您可以使用内联记录,它为您提供了记录语法的良好接口 - plus,您可以拥有可变字段 - 与元组语法具有相同的内存表示。

type ty =
| FunTy of {
forall : ty list;
p_tys : ty list;
ret_ty : ty
}
...

您有一些工具来操作包含的记录,但是(与元组语法中的参数" tuple "没有什么不同)它不是一级值(请参阅上面链接的文档了解更多详细信息)。

这是一个风格问题,所以我会记下我的看法。

在这个特殊的例子中,我们可以选择使用元组指定Variant构造函数还是使用record,即使我认为对于太多的字段,也应该使用record。

模式匹配无论如何都是足够的,无论是元组还是记录。

无论是元组还是记录,在处理值时都必须指定所有字段。

然而,真正的优势来自于处理太多字段的记录,如

  1. 记录字段可以通过键来识别,这样管理起来更方便,并且字段以顺序无关的方式处理,这意味着作者可以更好地控制。
  2. 元组字段是顺序显著的,这意味着作者在处理元组数据
  3. 时必须小心。

虽然元组在内存方面会更小,但是当字段数量增加时,记录确实有优势。

此意见严格针对元组或记录。任何其他组合,可能会遵循不同的意见…从我。: -)

当您看到构造函数接受许多参数的变体类型时,您可能希望考虑以另一种方式使用更多的间接方式。考虑一个简单的、人为的例子,指定一个类型来构建一个三角形。我们需要在2D或3D空间中存储每个角的坐标。

type triangle = 
Triangle_2d of float * float * (* Point A *) 
float * float * (* Point B *)
float * float   (* Point C *)
| Triangle_3d of float * float * float * (* Point A *)
float * float * float * (* Point B *)
float * float * float   (* Point C *)

谈论不舒服。所以我们用records

type triangle = 
Triangle_2d of { ax : float; ay : float; 
bx : float; by : float;
cx : float; cy : float }
| Triangle_3d of { ax : float; ay : float; az : float;
bx : float; by : float; bz : float;
cx : float; cy : float; cz : float }

但是当我们真正思考它时,我们不只是指定坐标吗?也许我们应该创建一个坐标类型

type coordinate = 
Coord_2d of { x : float; y : float }
| Coord_3d of { x : float; y : float; z : float }

那么我们的三角形类型就是:

type triangle = 
Triangle_2d of { a : coord; b : coord } 
| Triangle_3d of { a : coord; b : coord; c : coord }

甚至:

type triangle = 
Triangle_2d of coord * coord 
| Triangle_3d of coord * coord * coord

它看起来确实干净多了,但它也让我们把问题分解成更小的部分。如果我想计算三角形上两个顶点之间的距离,我不需要对整个三角形做数学运算。我可以简单地定义一个函数来处理坐标,我可以在这个层次上处理二维和三维坐标的区别。我甚至可以将其分解并编写将3D坐标投影到给定轴或平面上的函数。

相关内容

  • 没有找到相关文章

最新更新