不规则的孔types分辨率

我最近发现types的洞与certificate上的模式匹配相结合,在Haskell中提供了非常好的Agda类体验。 例如:

{-# LANGUAGE DataKinds, PolyKinds, TypeFamilies, UndecidableInstances, GADTs, TypeOperators #-} data (==) :: k -> k -> * where Refl :: x == x sym :: a == b -> b == a sym Refl = Refl data Nat = Zero | Succ Nat data SNat :: Nat -> * where SZero :: SNat Zero SSucc :: SNat n -> SNat (Succ n) type family a + b where Zero + b = b Succ a + b = Succ (a + b) addAssoc :: SNat a -> SNat b -> SNat c -> (a + (b + c)) == ((a + b) + c) addAssoc SZero bc = Refl addAssoc (SSucc a) bc = case addAssoc abc of Refl -> Refl addComm :: SNat a -> SNat b -> (a + b) == (b + a) addComm SZero SZero = Refl addComm (SSucc a) SZero = case addComm a SZero of Refl -> Refl addComm SZero (SSucc b) = case addComm SZero b of Refl -> Refl addComm sa@(SSucc a) sb@(SSucc b) = case addComm a sb of Refl -> case addComm b sa of Refl -> case addComm ab of Refl -> Refl 

真正好的是,我可以用一个types的洞replaceRefl -> exp结构的右边,我的洞目标types更新certificate,就像在Agda的rewriteforms一样。

但是,有时这个洞只是不能更新:

 (+.) :: SNat a -> SNat b -> SNat (a + b) SZero +. b = b SSucc a +. b = SSucc (a +. b) infixl 5 +. type family a * b where Zero * b = Zero Succ a * b = b + (a * b) (*.) :: SNat a -> SNat b -> SNat (a * b) SZero *. b = SZero SSucc a *. b = b +. (a *. b) infixl 6 *. mulDistL :: SNat a -> SNat b -> SNat c -> (a * (b + c)) == ((a * b) + (a * c)) mulDistL SZero bc = Refl mulDistL (SSucc a) bc = case sym $ addAssoc b (a *. b) (c +. a *. c) of -- At this point the target type is -- ((b + c) + (n * (b + c))) == (b + ((n * b) + (c + (n * c)))) -- The next step would be to update the RHS of the equivalence: Refl -> case addAssoc (a *. b) c (a *. c) of Refl -> _ -- but the type of this hole remains unchanged... 

此外,即使目标types不一定排列在certificate内,如果我从Agda粘贴整个东西,它仍然检查罚款:

 mulDistL' :: SNat a -> SNat b -> SNat c -> (a * (b + c)) == ((a * b) + (a * c)) mulDistL' SZero bc = Refl mulDistL' (SSucc a) bc = case (sym $ addAssoc b (a *. b) (c +. a *. c), addAssoc (a *. b) c (a *. c), addComm (a *. b) c, sym $ addAssoc c (a *. b) (a *. c), addAssoc bc (a *. b +. a *. c), mulDistL' abc ) of (Refl, Refl, Refl, Refl, Refl, Refl) -> Refl 

你有什么想法,为什么会发生这种情况(或者我怎样才能以强有力的方式进行证据重写)?

这是因为值是在运行时确定的。 它可以根据运行时input的内容实现值的转换,因此假定该孔已经更新。