我想定义一个运算符l_op : A list * A list -> A list
,其实现需要另一个运算符op : A * A -> A
。给定a0: A
,但对于所有a1 : A
op a0 a1
总是返回A
的结果,对于某些a1
,结果会使更有意义比其他a1
。
直觉l_op al0 al1
需要一个匹配策略,它会al1
找到op
的有意义的元素,对于al0
的每个元素。然后,op
的结果列表是l_op
的结果。
所以我需要衡量含义。
一种可能的选择是,可以定义函数measure: A * A * A -> int
。例如,measure a0 a1 (op a0 a1)
给出1到10之间的int,表示op a0 a1
有意义。然后,在l_op al0 al1
的实施中,对于a0
的每个al0
,我可以找到a1
,measure a0 a1 (op a0 a1) >= measure a0 a1' (op a0 a1') for all a1' in al1
。然后我从两个列表中删除a0
和a1
,并匹配其余的两个列表...
另一个选择是,我将op
更改为op : A * A -> A * int
,其中整数表示操作有意义。然后,在l_op al0 al1
的实施中,对于a0
的每个al0
,我可以找到a1
for all a1' in al1, m1 >= m1' where (_, m1), (_, m1') = op a0 a1, op a0 a1'
。
第二种选择的优点是,我们可以保存一些代码,因为我们可以在执行op a0 a1
时计算测量值。缺点是我发现签名op : A * A -> A * int
不如op : A * A -> A
好看。
所以我的问题是:
1)这种测量功能有一个常规词(可能以h
开头),但我忘了它,有人能提醒吗?
2)你认为int
是一个很好的测量类型吗?也许我们可以为此定义一种类型......最传统的方式是什么?
3)我上面提到的哪个选择更好?或者有没有人有更好的主意?
答案 0 :(得分:2)
这种测量功能有一个常规词(可能以h开头),
也许是“启发式”?它来自古希腊语,用于“发现,发现”,并在计算机科学中用于命名寻找“足够好”结果的方法,通常以更简单但几乎同样有效的方式逼近完美行为。这里非常合适(除非你的“意义测量”真的是一个启发式/近似值),但是以'h'开头。
我建议您将测量值称为“得分”或“重量”。
你认为int是一个很好的测量类型吗?也许我们可以为此定义一种类型......最传统的方式是什么?
取决于您的测量方式的定义。结果需要多少结构(例如,您可能希望保持测量的合理性,需要更丰富的结构)?测量时使用什么样的操作?如果你只使用加法和常量,int
没问题,如果你使用除法等,可能需要float
。在所有情况下,您可能需要一种可以比较其值的类型。
我想在大多数情况下int
都可以,否则你将能够相对轻松地改变主意。如果您打算更改此设置,则可以使用类型别名:
type measure = int
这样,您可以在大部分代码中使用measure
代替int
,之后无需替换所有匹配项。也就是说,在OCaml中,由于推理,我们通常不会编写很多类型的注释,因此在实践中我不希望您的输入选择的细节在很多代码中传播。
我上面提到的哪个选择更好?或者有没有人有更好的主意?
我会选择第二个选择。我怀疑“计算结果”的A -> A -> A
操作和“计算结果含义”的A -> A -> int
操作之间存在一些冗余。通过同时执行这两个操作(A -> A -> A * int
),您可以重用相同的逻辑结构,这使得通信更清晰(并使用更少的代码)。如果恰恰相反,这两个操作是完全无关的,你可以考虑使用两个单独的运算符(但我仍然使用A -> A -> int
进行评分;如果你需要得到结果来衡量意义,你仍然可以调用第一个内部运作。)