Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pattern matching with Kleene star on structure type in Racket

Tags:

scheme

racket

I started playing with Racket pattern matching system recently and got into a problem i can't understand.

If i do:

(match (list 1 2 3 4 5 6 7 8 9 10 11 12)
    [(list _ x y z ...) (list y ': x)]) 

in REPL i get

'(3 : 2)

as my desired result.

If i do:

(match (current-date)
    [(date* _ x y z ...) (list y ': x)])

or

(match (date* 5 18 13 18 11 2011 5 321 #f 3600 0 "W. Europe Standard Time")
    [(date* _ x y z ...) (list y ': x)])

i get this error:

match: wrong number for fields for structure date*: expected 12 but got 5 in: (_ x y z ...)

i suspect that the Kleene star ... does not work with struct type for some reason. Why is it so?

like image 802
mentus Avatar asked Nov 18 '11 12:11

mentus


People also ask

What does match do in Racket?

The match form supports pattern matching on arbitrary Racket values, as opposed to functions like regexp-match that compare regular expressions to byte and character sequences (see Regular Expressions). The match form takes the result of target-expr and tries to match each pattern in order.

Which character is used for the pattern matching?

The simplest and very common pattern matching character operators is the . This simply allows for any single character to match where a . is placed in a regular expression. For example /b.t/ can match to bat, bit, but or anything like bbt, bct .... Square brackets ( [..] )

Which clause is used for pattern matching in SQL?

The LIKE operator provides standard pattern matching in SQL that is always used after a WHERE clause. It matches any pattern based on some conditions provided using the wildcard characters.

Which language is required when pattern matches with strings?

Short for regular expression, a regex is a string of text that allows you to create patterns that help match, locate, and manage text. Perl is a great example of a programming language that utilizes regular expressions.


2 Answers

It seems that what you really want to do is match a subset of the fields in a struct, rather than actually bind the rest of the fields in the struct to (z ...). In this case, you may want to try using the struct* match pattern instead.

Here's an example:

(match (date* 5 18 13 18 11 2011 5 321 #f 3600 0 "W. Europe Standard Time")
   [(struct* date ([minute x] [hour y])) (list y ': x)])
like image 197
Asumu Takikawa Avatar answered Oct 17 '22 04:10

Asumu Takikawa


i suspect that the Kleene star ... does not work with struct type for some reason.

Correct. The ... notation, and the related ..k and ___ and __k notations, aren't really a general feature of matching, but rather a specific feature of list-matching and hash-table-matching and so on. If you examine the formal production in the documentation, you'll see that some types of subpatterns accept lvp (which is defined as either pat, or pat followed by ... or one of its friends) in various places, whereas others only accept pat.

Why is it so?

I guess it's simply that ... is used to translate part of a list or vector or hash-table or whatnot into its own list, and there's no sensible way to do that for a fixed-length struct. It may be worth pointing out that ... behaves differently for different types — for example, it can be used to extract a list of the keys in a hash-table — so the only reason to support it for structs would be if there were a specific analogous operation that would make sense for structs. I don't think there is one.

like image 38
ruakh Avatar answered Oct 17 '22 05:10

ruakh