I am looking for a concept in type theory that I am sure has probably been explored, but do not know the name behind.
Let's consider a ML-like language with product and sum types and a Hindley-Milner like type system. I'll use OCaml syntax.
I'm wondering about ways two different values can be different.
Use
My use case is writing "clearer" error messages in a xUnit-like library: if two values are different when they were expected to be equal, this can help build a clearer better message:
Before:
Values differ: expected
{x = [1;2;3;4], y = "a long string"}
, got{x = [1;2;3;3], y = "a long string"}
After:
Values differ: at position
.x[3]
, expected 4, got 3.
(there might be a relation with functional lenses since we're ultimately constructing a lens to a smaller value which differs).
Product types
For example:
type p =
{ x : int
; y : string
}
Equality can be defined as:
let equal a b =
equal_int a.x b.x && equal_string a.y b.y
But it's also possible to reify the differences:
type delta_p =
| Equal
| Diff_x of int * int
| Diff_y of string * string
let diff_p a b =
if not (equal_int a.x b.x) then
Diff_x (a.x, b.x)
else if not (equal_string a.y b.y) then
Diff_y (a.y, b.y)
else
Equal
(it might make sense to define a delta_int
type as int * int
to show that it is recursive)
Sum types
For a sum type there are more ways to differ: having a different constructor, or a different value
type s = X of int | Y of string
type ctor_s =
| Ctor_X
| Ctor_Y
type delta_s =
| Equal
| Diff_ctor of ctor_s * ctor_s
| Diff_X of int * int
| Diff_Y of string * string
let diff_s a b = match (a, b) with
| X xa, X xb ->
if equal_int xa xb then
Equal
else
Diff_X (xa, xb)
| (* Y case similar *)
| X _, Y _ -> Diff_ctor (Ctor_X, Ctor_Y)
| Y _, X _ -> Diff_ctor (Ctor_Y, Ctor_X)
What's the name of this concept? Where can I learn more about this?
Thanks!