【问题标题】:Need to match a tuple from a list in OCaml需要匹配 OCaml 列表中的元组
【发布时间】:2015-03-23 21:23:59
【问题描述】:

我需要创建一个函数 rec assoc (d,k,l),它采用三元组 (d,k,l) 其中 l 是键值对列表 [(k1,v1);(k2,v2 );...] 并找到第一个等于 k ​​的 ki。如果找到这样的 ki,则返回 vi。否则,返回默认值 d。它需要是尾递归的

这是我制作的函数:

let rec assoc (d,k,l)  = match l with
  |[]-> d
  |(a,b)::t ->  
  if (a==k) then b
  else assoc(d,k,t)
;;

我的逻辑是获取列表 l 的头部,如果列表中元组的第一部分与 k 匹配,我返回元组的第二部分。 如果不是,那么我想在列表的尾部再次调用该函数,以便检查每个元素。如果整个列表被遍历到空列表而没有找到匹配项,我想返回 d。出于某种原因,无论我给它什么列表,它总是返回 d 。这可能是什么原因。

这里应该给出一些示例输出:

# assoc (-1,"jeff",[("sorin",85);("jeff",23);("moose",44)]);;
- : int = 23
# assoc (-1,"bob",[("sorin",85);("jeff",23);("moose",44)("margaret",99)]);;
- : int = -1 

我的两个都返回 -1

【问题讨论】:

  • 通常情况下,OCaml 程序员不会像您那样传递元组中的所有参数。如let rec assoc d k = function.

标签: ocaml


【解决方案1】:

请勿使用== 进行比较。这是一种特殊目的的“物理平等”。使用= 进行比较。

(除此之外,您的代码看起来很棒。)

比较运算符在Pervasives module 中定义。以下是=(正常相等比较)和==(物理相等比较)的描述:

e1 = e2 测试 e1 和 e2 的结构相等性。可变结构(例如引用和数组)当且仅当它们的当前内容在结构上相等时才相等,即使两个可变对象不是同一个物理对象。函数值之间的相等会引发 Invalid_argument。循环数据结构之间的平等可能不会终止。

e1 == e2 测试 e1 和 e2 的物理相等性。对于可变类型,例如引用、数组、字节序列、具有可变字段的记录和具有可变实例变量的对象,当且仅当 e1 的物理修改也影响 e2 时,e1 == e2 为真。在非可变类型上, ( == ) 的行为取决于实现;但是,可以保证 e1 == e2 意味着比较 e1 e2 = 0。

一般来说,您不应该在代码中使用==,除非您想要此处描述的特定(弱)相等性测试。或者,只是不要使用它:-)

【讨论】:

  • 确实修复了我的代码。但是我很困惑为什么我需要为此使用 = 而不是 == 。你能解释一下吗,我认为你必须使用 == 来比较和 = 来设置值。
  • 这些是 C 和其他基于 C 的语言的约定 :-) 但不是 OCaml。我添加了一些关于=== 的细节。
  • 另请注意,多态比较运算符= 不适用于比较抽象数据结构,例如集合。这是因为= 只是比较了它的两个操作数的表示,这在抽象数据结构的情况下通常是不合适的。一个好的经验法则是仅将= 用于具体类型。
猜你喜欢
  • 2019-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-14
  • 2012-09-23
  • 1970-01-01
相关资源
最近更新 更多