I am having trouble understanding how type applications work. Why can sing in refuteRefuteKnockable be used without a type application when the call to sing in knockableOrOpened will fail to type check without a type application?
refuteRefuteKnockable :: SingI s => Refuted (Refuted (Knockable s)) -> Knockable s
refuteRefuteKnockable rrK =
case isKnockable $ sing of
Proved k -> k
Disproved rK -> absurd $ rrK rK
knockableOrOpened :: forall s. SingI s => Or Knockable ((:~:) Opened) s
knockableOrOpened =
case sing @s of
SOpened -> OrRight $ Refl
SClosed -> OrLeft KnockClosed
SLocked -> OrLeft KnockLocked
I am working from the following codebase: https://github.com/mstksg/inCode/blob/master/code-samples/singletons/Door3.hs