英文:
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 : '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>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论