如何在OCaml中简洁地展开代数数据类型?

如何在OCaml中简洁地展开代数数据类型?,ocaml,algebraic-data-types,Ocaml,Algebraic Data Types,有没有一种好方法可以在OCaml中简洁地展开代数数据类型?例如,考虑下面的代码,它定义了两种不同类型的数学函数 type ftype = | Quadratic of {alpha : float; a : float array; aa : float array} | General of {eval : float array->float} type m

有没有一种好方法可以在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)

是的,代码不安全,无法编译。这就是说,为了调试的目的,接近这一点的东西会很好,这样我们就不必编写冗长的代码来打开一个值。有没有一个好方法可以实现这一点?

如果只是为了调试目的,您可以随时编写:

let { typ = General { eval; } ; } = f in
let y = eval x in
...
当然,编译器会打印警告8(非穷举模式匹配)


我不认为你能做得更简洁,求和类型是为了可读和安全。抱歉,不要太快。

当您在顶层玩代码时,使用可反驳(即不完整)模式是完全可以的,例如

let [1;3;5] = List.filter is_odd [1;2;3;4;5]
为了防止顶级警告破坏您的体验,只需使用

#warnings "-P";;

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

您可以使用let绑定来分解结构:
let y=let{typ=General(f)}=f in f.eval(x)
。可以说不那么难看,但在这种情况下肯定不会更短。不过,它将更好地处理嵌套问题。