# How to use union types?

**URL:** <https://racket.discourse.group/t/how-to-use-union-types/2537>\
**Category:** Questions & Answers\
**Tags:** typed-racket\
**Created:** [November 26, 2023, 3:37pm UTC](https://racket.discourse.group/t/how-to-use-union-types/2537 "2023-11-26T15:37:17Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kalimehtar](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/kalimehtar/32/394_2.png) [@Kalimehtar](https://racket.discourse.group/u/Kalimehtar)\
**Post date:** [November 26, 2023, 3:37pm UTC](https://racket.discourse.group/t/how-to-use-union-types/2537/1 "2023-11-26T15:37:17Z")

</div>

If I try

```scheme
(: foo (-> (U Positive-Exact-Rational Negative-Exact-Rational) Positive-Exact-Rational
           (U Positive-Exact-Rational Negative-Exact-Rational)))
(define (foo a b) (* a b))

```

I get type mismatch.

But both

```scheme
(: foo (-> Positive-Exact-Rational Positive-Exact-Rational
           (U Positive-Exact-Rational Negative-Exact-Rational)))
(define (foo a b) (* a b))

```

and

```scheme
(: foo (-> Negative-Exact-Rational Positive-Exact-Rational
           (U Positive-Exact-Rational Negative-Exact-Rational)))
(define (foo a b) (* a b))

```

checked fine.

Is it a bug in checker, or should I somehow tell it to union the types for `*`?

---

<div class="post-metadata">

**Author:** ![EmEf](https://avatars.discourse-cdn.com/v4/letter/e/53a042/32.png) [@EmEf](https://racket.discourse.group/u/EmEf)\
**Post date:** [November 26, 2023, 4:09pm UTC](https://racket.discourse.group/t/how-to-use-union-types/2537/2 "2023-11-26T16:09:01Z")

</div>

The existing type of \* does not include your desired combination:

```scheme
> (:query-type/result * (U Positive-Exact-Rational Negative-Exact-Rational))
(case->
 (-> Negative-Exact-Rational Negative-Exact-Rational Negative-Exact-Rational Negative-Exact-Rational)
 (-> Positive-Exact-Rational Negative-Exact-Rational Negative-Exact-Rational)
 (-> Negative-Exact-Rational Positive-Exact-Rational Negative-Exact-Rational)
 (-> Negative-Exact-Rational Negative-Exact-Rational Positive-Exact-Rational)
 (-> Negative-Exact-Rational Negative-Exact-Rational)
 (-> Positive-Exact-Rational * Positive-Exact-Rational))

```

Conjecture: Our \* may yield a variant of ‘zero (according to the type checker). And indeed, if you add Zero to the result type of your first expression, the checker verifies the theorem:

```scheme
#lang typed/racket

(: foo (-> (U Positive-Exact-Rational Negative-Exact-Rational) Positive-Exact-Rational
           (U Positive-Exact-Rational Negative-Exact-Rational Zero)))
(define (foo a b) (* a b))

```

(To someone who knows numerics well: Is it possible that multiplying two numbers of the given type yields something close to 0 with exact rationales? My reasoning says ‘no’ and we could change the type of \* to include the desired outcome.)

---

<div class="post-metadata">

**Author:** ![Kalimehtar](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/kalimehtar/32/394_2.png) [@Kalimehtar](https://racket.discourse.group/u/Kalimehtar)\
**Post date:** [November 26, 2023, 4:37pm UTC](https://racket.discourse.group/t/how-to-use-union-types/2537/3 "2023-11-26T16:37:28Z")

</div>

It has

```scheme
(-> Negative-Exact-Rational Positive-Exact-Rational Negative-Exact-Rational)

```

and

```scheme
(-> Positive-Exact-Rational * Positive-Exact-Rational)

```

So last can be specified to

```scheme
(-> Positive-Exact-Rational Positive-Exact-Rational Positive-Exact-Rational)

```

From

```scheme
(-> Negative-Exact-Rational Positive-Exact-Rational Negative-Exact-Rational)
(-> Positive-Exact-Rational Positive-Exact-Rational Positive-Exact-Rational)

```

one can derive, that

```scheme
(-> (U Negative-Exact-Rational Positive-Exact-Rational) Positive-Exact-Rational 
      (U Negative-Exact-Rational Positive-Exact-Rational ))

```

---

<div class="post-metadata">

**Author:** ![Kalimehtar](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/kalimehtar/32/394_2.png) [@Kalimehtar](https://racket.discourse.group/u/Kalimehtar)\
**Post date:** [November 26, 2023, 4:44pm UTC](https://racket.discourse.group/t/how-to-use-union-types/2537/4 "2023-11-26T16:44:07Z")

</div>

This works:

```scheme
(: foo (-> (U Positive-Exact-Rational Negative-Exact-Rational) Positive-Exact-Rational
           (U Positive-Exact-Rational Negative-Exact-Rational)))
(define (foo a b) 
  (if (> a 0)
      (* a b)
      (* a b)))

```

But excessive conditional looks very ugly...

---

<div class="post-metadata">

**Author:** ![Kalimehtar](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/kalimehtar/32/394_2.png) [@Kalimehtar](https://racket.discourse.group/u/Kalimehtar)\
**Post date:** [November 26, 2023, 4:50pm UTC](https://racket.discourse.group/t/how-to-use-union-types/2537/5 "2023-11-26T16:50:58Z")

</div>

This works too

```scheme
(: foo (-> (U Positive-Exact-Rational Negative-Exact-Rational) (U Positive-Exact-Rational Negative-Exact-Rational)
           (U Positive-Exact-Rational Negative-Exact-Rational)))
(define (foo a b) 
  (if (> a 0)
      (if (> b 0)
          (* a b)
          (* a b))
      (if (> b 0)
          (* a b)
          (* a b))))

```

---

<div class="post-metadata">

**Author:** ![EmEf](https://avatars.discourse-cdn.com/v4/letter/e/53a042/32.png) [@EmEf](https://racket.discourse.group/u/EmEf)\
**Post date:** [November 26, 2023, 6:00pm UTC](https://racket.discourse.group/t/how-to-use-union-types/2537/6 "2023-11-26T18:00:19Z")

</div>

Zero in PLs are weird:

```scheme
(: x (U Positive-Exact-Rational Negative-Exact-Rational))
(define x 0)

```
