# Typed Racket: map list items while remembering individual types?

**URL:** <https://racket.discourse.group/t/typed-racket-map-list-items-while-remembering-individual-types/1701>\
**Category:** Questions & Answers\
**Tags:** question, typed-racket\
**Created:** [February 12, 2023, 12:19am UTC](https://racket.discourse.group/t/typed-racket-map-list-items-while-remembering-individual-types/1701 "2023-02-12T00:19:42Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![cadence](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/cadence/32/998_2.png) [@cadence](https://racket.discourse.group/u/cadence)\
**Post date:** [February 12, 2023, 12:19am UTC](https://racket.discourse.group/t/typed-racket-map-list-items-while-remembering-individual-types/1701/1 "2023-02-12T00:19:42Z")

</div>

First, consider lists where all list items are the same time. I already know that this isn't possible the easy way due to nested polymorphic functions:

```scheme
(map values '(5 6 7))
/!\ Type Checker: Polymorphic function `map' could not be applied to arguments

```

and I have to (inst values) to make it work:

```scheme
(map (inst values Integer) '(5 6 7 8))
- : (Pairof Integer (Listof Integer))
'(5 6 7 8)

```

* * *

My real question is about mixed type lists. This is the shortest code that I could come up that maps the list while remembering the type of each list item. Notice how on this one I don't need to (inst values), instead, I have to type the input as (List a ...):

```scheme
((lambda #:forall (a ...) ([xs : (List a ...)]) (map values xs)) '(5 a "s"))
- : (List Positive-Byte 'a String)
'(5 a "s")

```

**Is there a way to do this that's more intuitive/requires fewer keystrokes?** I've played around a fair bit and I can't find a shorter version. It would be okay if I could turn this into a macro, but I can't figure out how to do that either, because `...` has special meaning in define-syntax-rule.

I don't want to use (inst values Any) because it would turn my list into (Listof Any), which forgets the list's length and the type of each item.

---

<div class="post-metadata">

**Author:** ![samth](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/samth/32/3_2.png) [@samth](https://racket.discourse.group/u/samth)\
**Post date:** [February 13, 2023, 9:22pm UTC](https://racket.discourse.group/t/typed-racket-map-list-items-while-remembering-individual-types/1701/2 "2023-02-13T21:22:19Z")

</div>

The feature you're using in the last example is exactly what's intended to express the pattern you want.

---

<div class="post-metadata">

**Author:** ![LiberalArtist](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/liberalartist/32/151_2.png) [@LiberalArtist](https://racket.discourse.group/u/LiberalArtist)\
**Post date:** [February 13, 2023, 11:29pm UTC](https://racket.discourse.group/t/typed-racket-map-list-items-while-remembering-individual-types/1701/3 "2023-02-13T23:29:35Z")

</div>

> [@cadence](#):
>
> It would be okay if I could turn this into a macro, but I can't figure out how to do that either, because `...` has special meaning in define-syntax-rule.

You can escape `...` in templates by writing `(... ...)`.

---

<div class="post-metadata">

**Author:** ![cadence](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/cadence/32/998_2.png) [@cadence](https://racket.discourse.group/u/cadence)\
**Post date:** [February 15, 2023, 10:28am UTC](https://racket.discourse.group/t/typed-racket-map-list-items-while-remembering-individual-types/1701/4 "2023-02-15T10:28:32Z")

</div>

Thanks for the help! I ended up with this final code just like you described.

```scheme
(define-syntax-rule (map-elements fn lst)
  (... ((lambda #:forall (a ...) ([xs : (List a ...)]) (map fn xs)) lst)))
```
