# Re: [racket-users] Defining algebraic data types?

```On Mon, Feb 5, 2018 at 6:36 PM, HiPhish <hiph...@openmailbox.org> wrote:
> Why would that be a problem? The caller has to provide a function for
> and "multiplying" an N, and as long as I define what it means to multiply
> and
> add strings it shouldn't matter that I'm using a dual number where both
> components are strings.```
```
The problem is that the definition of `(Dual-Number N)` includes `N`,
and therefore

(Dual-Number (Dual-Number String)) might either be a (D (D "x" "y") (D
"x" "y")) or just (D "x" "y"). Therefore checking D? can't tell that
you're in the `D` case because both cases could be a `D` case.

Sam

>
> But I think this is a case of the rectangle-square problem: dual scalars and
> a
> dual vectors a both a subset of dual quaternions that contain less
> information
> than their supertype. I guess what I'm really looking for is a way to
> "magically" promote objects.
>
> A quaternion is an object of
>
>   H = {a + bi + cj + dk | a,b,c,d ∈ R},
>
> a vector is an object of
>
>   V = {ai + bj + ck | a,b,c ∈ R},
>
> but we can also view H as
>
>   H = R × V = {(a, v) | a ∈ R, v ∈ V}.
>
> The first definition of H is how it is usually defined and written out, but
> the
> second definition makes it easier to compute the product:
>
>   (p_r, p_v) (q_r, q_v) = (p_r q_r - p_v ⋅ q_v, p_r q_v + q_r p_v + p_v ×
> q_v).
>
> So far this is a simple hierarchy. But the set of scalars and the set of
> vectors can be embedded in the set of quaternions:
>
>   R → H, a ↦ (a, 0)  and V → H, v ↦ (0, v)
>
> We can also define things like the "quaternion cross product" and
> "quaternion
> dot product" for quaternions where the scalar part is zero:
>
>   (0, p) × (0, q) := (p, p × q)
>   (0, p) ⋅ (0, q) := (p ⋅ q, 0)
>
> I'm starting to think this is becoming a pointless exercise. Maybe I should
> just limit myself to "dual quaternions are a pair of quaternions" and
> "quaternions are pairs of a scalar and a vector" and forget about the magic
> subtyping.
>
>
> On Tuesday, February 6, 2018 at 12:01:42 AM UTC+1, Sam Tobin-Hochstadt
> wrote:
>>
>> I'm not sure how the "If" got there.
>>
>> But to say more, consider your function:
>>
>>   (: dual-* (∀ (N) (→ (Dual-Number N) (Dual-Number N) (→ N N N) (→ N N
>> N) (Dual-Number N))))
>>   (define (dual-* d1 d2 * +)
>>     (cond
>>       [(D? d1)
>>        (D
>>          (D-real d1)
>>          (D-dual d1))]
>>       [else (D d1 d1)]))
>>
>> Now you imagine instantiating `N` with things like `(Vector3 Real)`,
>> but if we instantiated it instead with `(Dual-Number String)`, then
>> you'd have a problem.
>>
>> Sam
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an