Pattern matching on a record 记录上的模式匹配

huangapple go评论65阅读模式
英文:

Pattern matching on a record

问题

以下是翻译好的部分:

但它不能编译。{Nil; _; Nil; _} 有什么问题?

英文:

I have this:

type 'a queue = {f : 'a stream; lenf : int; r : 'a stream; lenr : int};;

let empty :'a queue = {f = Nil; lenf = 0; r = Nil; lenr = 0};;

let is_empty (q :'a queue) = 
  match q with
  | {Nil; _; Nil; _} -> true
  | {_; _; _; _} -> false;;

But it doesn't compile. What is wrong with {Nil; _; Nil; _}?

答案1

得分: 2

Fields of a record are accessed by name, not by order. So you need to give field names in a record pattern.

记录的字段通过名称访问而不是通过顺序因此您需要在记录模式中提供字段名称

You can leave out fields if you don't care about them, i.e., if they can match anything. There is a warning (Warning 9) for incompletely specified record patterns. If you include a trailing _ the compiler won't warn you that some fields weren't specified even if Warning 9 is in effect:

如果您不关心字段可以省略它们如果它们可以匹配任何内容对于未完全指定的记录模式会有一个警告警告9)。如果包括一个尾随的 `_`即使警告9生效编译器也不会警告您未指定某些字段

英文:

Fields of a record are accessed by name, not by order. So you need to give field names in a record pattern.

# let is_empty (q : 'a queue) =
      match q with
      | { f = Nil; lenf = _; r = Nil; lenr = _ } -> true
      | _ -> false
  ;;
val is_empty : 'a queue -> bool = <fun>

You can leave out fields if you don't care about them, i.e., if they can match anything. There is a warning (Warning 9) for incompletely specified record patterns. If you include a trailing _ the compiler won't warn you that some fields weren't specified even if Warning 9 is in effect:

# let is_empty (q : 'a queue) =
      match q with
      | { f = Nil; r = Nil; _ } -> true
      | _ -> false
  ;;
val is_empty : 'a queue -> bool = <fun>

答案2

得分: 1

Alternatively, you might simply access the pertinent record fields and use a boolean expression.

# let is_empty (q : 'a queue) = 
    q.f = Nil && q.r = Nil;;
val is_empty : 'a queue -> bool = <fun>

The match expression is a great tool, but it's not the only tool you have in OCaml. Use the best tool for the job.

One more thing...

You can pattern-match in the arguments of a function.

# let is_empty ({f; r; _} : 'a queue) =
    f = Nil && r = Nil;;
val is_empty : 'a queue -> bool = <fun>

And if you still needed to bind the name q to the whole queue, you could use as. Optionally, a leading underscore in the name of that binding will suppress the unused variable warning.

# let is_empty ({f; r; _} as q : 'a queue) =
    f = Nil && r = Nil;;
Line 1, characters 14-28:
Warning 26 [unused-var]: unused variable q.
val is_empty : 'a queue -> bool = <fun>
# let is_empty ({f; r; _} as _q : 'a queue) =
    f = Nil && r = Nil;;
val is_empty : 'a queue -> bool = <fun>
英文:

Alternatively, you might simply access the pertinent record fields and use a boolean expression.

# let is_empty (q : &#39;a queue) = 
    q.f = Nil &amp;&amp; q.r = Nil;;
val is_empty : &#39;a queue -&gt; bool = &lt;fun&gt;

The match expression is a great tool, but it's not the only tool you have in OCaml. Use the best tool for the job.

One more thing...

You can pattern-match in the arguments of a function.

# let is_empty ({f; r; _} : &#39;a queue) =
    f = Nil &amp;&amp; r = Nil;;
val is_empty : &#39;a queue -&gt; bool = &lt;fun&gt;

And if you still needed to bind the name q to the whole queue, you could use as. Optionally, a leading underscore in the name of that binding will suppress the unused variable warning.

# let is_empty ({f; r; _} as q : &#39;a queue) =
    f = Nil &amp;&amp; r = Nil;;
Line 1, characters 14-28:
Warning 26 [unused-var]: unused variable q.
val is_empty : &#39;a queue -&gt; bool = &lt;fun&gt;
# let is_empty ({f; r; _} as _q : &#39;a queue) =
    f = Nil &amp;&amp; r = Nil;;
val is_empty : &#39;a queue -&gt; bool = &lt;fun&gt;

huangapple
  • 本文由 发表于 2023年4月17日 09:30:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76031155.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定