# \`match\` for parsing into hash

**URL:** https://racket.discourse.group/t/match-for-parsing-into-hash/3523
**Category:** Questions & Answers
**Created:** [January 29, 2025, 11:08pm UTC](https://racket.discourse.group/t/match-for-parsing-into-hash/3523 "2025-01-29T23:08:35Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![dstorrs](https://avatars.discourse-cdn.com/v4/letter/d/898d66/32.png) [@dstorrs](https://racket.discourse.group/u/dstorrs)
#### Post date: [January 29, 2025, 11:08pm UTC](https://racket.discourse.group/t/match-for-parsing-into-hash/3523/1 "2025-01-29T23:08:35Z")

</div>

```scheme
#lang racket

(match (list 7 2 3 7) ; displays: 7                                                                 
  [(list row b c row) row])

(match (list 7 2 3 (hash 7 'ok )) ; displays: (list 7 'ok)                                          
  [(list row b c (hash 7 val)) (list row val)])

;; (match (list 7 2 3 (hash 7 'ok )) ; should display: (list 7 'ok) but throws compiler error       
;; [(list row b c (hash row val)) (list row val)])                                                

(match (list 7 2 (hash 7 (hash 2 'ok))) ; displays: (list 7 'ok)                                    
  [(list row col c row-hash)
   #:do [(match-define (hash* (row col-hash)) row-hash)]
   #:do [(match-define (hash* (col val)) col-hash)]
   (list row val)])

```

The first and second matches work as expected. The third match throws a compiler error saying:

```scheme
; /Users/dstorrs/projects/sudoku/test.rkt:7:23: row: unbound identifier                             
; in: row   

```

Took me a minute to realize what was happening, namely that `id` bindings aren't available in other parts of the pattern, which means they aren't available in the `(hash ...)` clause.

The fourth one decomposes the nested hashes as expected but seems a bit clunky.

Is there a better way to do this?

---

<div class="post-metadata">

### Author: ![benknoble](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/benknoble/32/16_2.png) [@benknoble](https://racket.discourse.group/u/benknoble)
#### Post date: [January 30, 2025, 12:15am UTC](https://racket.discourse.group/t/match-for-parsing-into-hash/3523/2 "2025-01-30T00:15:13Z")

</div>

> [@dstorrs](#):
>
> Is there a better way to do this?

For a slight improvement: `#:do [body …]` has outer brackets because you have more than one body expression 🙂

---

<div class="post-metadata">

### Author: ![bakgatviooldoos](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/bakgatviooldoos/32/1381_2.png) [@bakgatviooldoos](https://racket.discourse.group/u/bakgatviooldoos)
#### Post date: [January 30, 2025, 5:35am UTC](https://racket.discourse.group/t/match-for-parsing-into-hash/3523/3 "2025-01-30T05:35:33Z")

</div>

Not a better way at all, but using shenanigans and the deprecated `hash-table`:

```scheme
(match (list 7 2 3 (hash 7 'ok))
  [(app reverse (list (hash-table [row val]) c b (== row)))
   (list row val)])

```

It does, however, highlight that it might be helpful to allow `==` to be used in the relatively new `hash` match-expander's key position?

```scheme
(match (list 7 2 3 (hash 7 'ok))  
  [(list row b c (hash (== row) val))
   (list row val)])

```

Of course, this depends on how these things are scoped, because this doesn't work either:

```scheme
(match (list 7 2 3 (hash 7 'ok))
  [(list row b c (hash-table [(== row) val]))
   (list row val)])

```
