I am playing with sum type parameters, and I'd like to specify types for parameters that play well together. For instance, I have a function that can take types (A, C) or (B, D) but I don't wont (A, D) or (B, C) to be valid. With sum types, f(A|B, C|D) makes every combo valid. Is there a way to impose that restriction?
type A = object
type B = object
type C = object
type D = object
proc `$`(x: A): string = "A"
proc `$`(x: B): string = "B"
proc `$`(x: C): string = "C"
proc `$`(x: D): string = "D"
# f is overspecified
proc f(x: A | B, y: C | D) =
echo (x, y)
# g is well specified
proc g*(x: A, y: C) = f(x, y)
proc g*(x: B, y: D) = f(x, y)
f(A(), D())
g(A(), C())
g(B(), D())
i see nothing wrong with your well-specified version, but there're many ways to achieve what you're after, including:
proc ghelper(xy:(A,C)|(B,D)): echo xy
proc g*[T,U](x:T,y:U)=ghelper((x,y))
#or
template g*(x,y) = ghelper((x,y))
#or full manual:
import macros
proc g[T,U](x:T, y:U) =
when (T is A and U is C) or (T is B and U is D):
echo (x,y)
else:
static:error("A,C or B,D expected, got: " & $T & "," & $U)