如何简洁地在OCaml中解包代数数据类型?

时间:2018-08-16 22:38:17

标签: ocaml algebraic-data-types

是否有一个很好的方法来简洁地解包OCaml中的代数数据类型?例如,请考虑以下代码,该代码定义了两种不同类型的数学函数

type ftype =                                                         
    | Quadratic of {alpha : float; a : float array; aa : float array}
    | General of {eval : float array->float}
type myfn = {                                                                   
    nvar : int;
    typ : ftype}  
let f = {                                                                       
    nvar = 2;                                                                   
    typ = General {eval = fun x-> x.(0) +. x.(1)}} 

出于调试目的,有时最好只是评估一个函数或在顶层检查其值。但是,如果要评估f,则需要使用类似

的代码
let x = [| 1.; 2. |]
let y = match f.typ with General(f) -> f.eval(x)

这有点丑陋,而且很难打,尤其是当分层深达几层时。我想定义某种语法,例如

let y = f.typ.General.eval(x)

是的,代码不安全,因此无法编译。也就是说,接近此值对于调试目的将是很好的,因此我们不必编写冗长的代码即可解开值。有什么好方法可以做到这一点吗?

2 个答案:

答案 0 :(得分:1)

如果仅出于调试目的,您可以随时编写:

let { typ = General { eval; } ; } = f in
let y = eval x in
...

当然,编译器会向您显示警告8(非穷举模式匹配)。

我认为您不能做得更简洁,求和类型的目的是易于阅读和安全。不好意思,对不起。

答案 1 :(得分:1)

在顶级代码中使用代码时,最好使用可重复使用(即不完整)的模式,例如

let [1;3;5] = List.filter is_odd [1;2;3;4;5]

要防止顶层破坏警告,请使用

禁用警告
#warnings "-P";;

(或“ -8”,是相同的,不要忘记键入前导#,它是指令的一部分,而不是提示符)。