Consider the following (very simplified) example of constraining a datatype via a side-condition on its values:
data Transport = Car | Foot | Boat
total wheels : (transport : Transport) -> {auto hasWheels : transport = Car} -> Int
wheels Car {hasWheels = Refl} = 4
wheels Foot {hasWheels = Refl} impossible
wheels Boat {hasWheels = Refl} impossible
Is there any way I can leave out or summarise the impossible
cases and still have Idris see the function as total? If I do leave a case out I get something like
Main.wheels is not total as there are missing cases
I also can't just have a catch-all case as the compiler doesn't know that the _
can't be Car so the second line doesn't type-check:
wheels Car {hasWheels = Refl} = 4
wheels _ {hasWheels = Refl} impossible
This gives
wheels _ is a valid case
I've looked through the ideas in this post about constraining datatypes but I don't see any approaches that help.
In the real code this is simplified from, there are a lot of cases which each need to be discharged separately, making it very unwieldy.