您可以在记录中使用两个字段来定义第三个字段吗?例如
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,而不是将它存储在一个字段中。
答案 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}