The following is a minimal example of a typechecking issue I’ve been
chasing after for a while. I have an either type that I’ve implemented,
mimicing the standard library’s option type:
datatype either_t0ype_bool_type
(a : t@ype+, b : t@ype+, bool) =
Left (a, b, true) of (a)
| Right (a, b, false) of (b)
stadef either = either_t0ype_bool_type
typedef Either (a:t0p, b:t0p) = [c : bool] either (a, b, c)
fun{a:t0p}{b:t0p} either_left .<>. (a:a):<> either(a, b, true) = Left(a)
fun{a:t0p}{b:t0p} either_right .<>. (b:b):<> either(a, b, false) = Right(b)
When I go to use it
fun do_either(x : int) : [n : nat; m : nat] Either (int n, int m) =
case+ x of
| x when x > 0 => either_left(0)
| x => either_right(1)
implement main0() =
let
val _ = do_either(~1)
in () end
attempts to typecheck this result in
481(line=15, offs=21) -- 511(line=15, offs=51): error(3): unsolved constraint: C3NSTRprop(main; S2Eapp(S2Ecst(>=); S2EVar(7), S2Eintinf(0)))
I’ve finally understood the reason for this. A call to either_left
will be able to infer the type for the left side (a
) as int 0
, which
satisfies the n >= 0
constraint that nat
has. However, either
still requires a type for the right hand side (b
), which has no
constraints put upon it in this case, so the constraint solving fails
showing that we cannot prove that the type for the right side satisfies
that the integer will provably be >= 0.
However, I can’t figure out how to solve this. My feeble attempts to do
either_left<[x:nat] int x>(0)
fail, and I feel like there should be a
clear way to solve this?