Is it possile to use core.match to do the following (silly example):
(defn summaries-film [film]
(match film
{:genre "Horror" :budget :guard #(< % 1000000) :star _} "Low budget horror"
{:genre "Comedy" :budget _ :star "Adam Sandler"} "Trash"
{:genre _ :budget _ :star "Emily Blunt"} "5 Stars"
:else "Some other film"))
??
I'd like to be able to pattern match over a map, but then have the :guard #(< % 10000)
bit? i.e. have a function in the pattern based on the value of the key in the map?
Is this possible, I know I can do this over a vector, but can't work out the syntax or if its possible with maps.
I know I can use destructuring, but I'd like to know if it's possible with pattern matching.
Thanks
You can use guards with maps, though the syntax is different. Wrap the pattern in a list and append :guard your-guard-fn
. The guard function will be invoked with the entire map, assuming the pattern matches otherwise:
({:foo 1} :guard #(= 1 (:foo %)))
Here's what it looks like with your example:
(defn summaries-film [film]
(match film
({:genre "Horror" :budget _ :star _} :guard #(< (:budget %) 100)) "Low budget horror"
{:genre "Comedy" :budget _ :star "Adam Sandler"} "Trash"
{:genre _ :budget _ :star "Emily Blunt"} "5 Stars"
:else "Some other film"))
(summaries-film {:genre "Horror" :budget 1 :star "Kelsey Grammer"})
;=> "Low budget horror"
(summaries-film {:genre "Horror" :budget 101 :star "Robert Forster"})
;=> "Some other film"