使用记录中的两个字段定义记录中的第三个字段

时间:2014-10-17 02:06:10

标签: ocaml

您可以在记录中使用两个字段来定义第三个字段吗?例如

type  t = { a : int; b : int; c : int } 
{ a = 1 ; b = 2; c = a * b};

甚至更好

type t = { a : int; b : int; c = a * b } 

或者Ocaml中有什么影响?我知道你可以很容易地编写一个函数来计算c,而不是将它存储在一个字段中。

3 个答案:

答案 0 :(得分:4)

如果要确保为字段创建具有特定含义的每个t,则可以使用模块系统。 private类型允许其他人访问该字段,同时禁止t直接创建(或突变,它有可变部分)。

看起来像这样:

module Foo : sig
  type t = private { a : int; b : int; c : int }
  val create : int -> int -> t
end = struct
  type t = { a : int; b : int; c : int }
  let create a b = { a; b; c = a * b; }
end

这是强制执行不变量的一种非常有效的方法,但它可能有点沉重。

答案 1 :(得分:3)

您提出的语法都不像我们今天所使用的那样在OCaml中工作。

您可以编写一个函数来构建记录:

# let mkt a b = { a; b; c = a * b };;
val mkt : int -> int -> t = <fun>
# mkt 2 3;;
- : t = {a = 2; b = 3; c = 6}

您可以使用对象类型,以便按需计算c

# class c a b = object method a = a method b = b method c = a * b end;;
class c :
  int -> int -> object method a : int method b : int method c : int end
# let x = new c 3 4;;
val x : c = <obj>
# (x#a, x#b, x#c);;
- : int * int * int = (3, 4, 12)

这是我能想到的最好的。

答案 2 :(得分:1)

存在1种无效方式。

让我们看一下Haskell代码:

data Rec = Rec {a::Int, b::Int, c::Int}

d = Rec {a = 2, b = 3, c = a d * b d}

> d
Rec {a = 2, b = 3, c = 6}

因此,要在OCaml中模拟相同的内容,我们必须更改位类型:

type  t = { a : int; b : int; c : int lazy_t} 

> let rec d = {a = 2; b = 3; c = lazy (d.a * d.b)};;
val d : t = {a = 2; b = 3; c = <lazy>}

> Lazy.force d.c;;
- : int = 6

> d
- : t = {a = 2; b = 3; c = lazy 6}