I am trying to write a weaken function for finite sets of integers. I am using the singletons package. I have defined and promoted addition, subtraction and predecessor functions, as well as proved some equations on them to help the type-checker. But the error I am getting is quite unrelated to all that.
weaken :: forall n m k . (SingI n, SingI m, SingI k, (Minus m n) ~ NatJust k) => Fin n -> Fin m
weaken ZF = gcastWith (apply Refl $ plus_minus sm sn sk) ZF
where sn = sing :: SNat n
sm = sing :: SNat m
sk = sing :: SNat k
weaken (SF n) = gcastWith (apply Refl $ succ_pred sm) (SF (weaken n))
where sn = sing :: SNat n
sm = sing :: SNat m
sk = sing :: SNat k
The error I am getting is on the recursive call of weaken (SF (weaken n)) and is the following: Could not deduce (SingI n1), where n1 is correctly inferred to be the type-level predecessor of type n. I could add a SingI (Pred n) constraint but this simply moves the problem one level down (GHC now says it can't deduce the equivalent of (SingI (Pred (Pred n)))).
How can I convince GHC that SingI (Pred n) follows from SingI n (and why doesn't the singletons package already do this)?
GHC.TypeLits, which ultimately provides us type-level non-negativeInteger-s, exports no functions that would let us do singleton runtime operations. For example, givenKnownNat aandKnownNat b, there is no standard function to produceKnownNat (a + b)at runtime.singletonssolves this by implementing the singletonNatoperations unsafely.singletonssubtraction function throws an error for negative results (and doesn't truncate to 0 as we'd wish), so we can't reuse that forpredand have to implement it ourselves:You can use
sPredto getSing (Pred n), thenwithSingIorsingInstanceto convert that intoSingI (Pred n).However, you probably shouldn't use
SingIinweaken. The purpose ofSingIis to plug around singleton parameters automatically in contexts where you don't use them for anything besides forwarding them to other functions. Instead just useSing, and you can avoidsingand type annotation noise. In my experienceSingis preferable toSingIin about 90% of the time forsingletonsprogramming.