如何帮助 GHC 推断出 `Arrows (Domains func) (CoDomain func) ~ func`
How to help GHC infer that `Arrows (Domains func) (CoDomain func) ~ func`
考虑 Arrows
、Domains
和 CoDomain
类型族定义 in the agda
codebase。
对于程序员来说很明显,它认为Arrows (Domains func) (CoDomain func) ~ func
。但是我无法通过 GHC 的类型检查器获得 curries (Proxy :: Proxy (Domains func)) (Proxy :: Proxy (CoDomain func)) undefined :: func
。这是因为 GHC 不够聪明,无法推断 Domains
和 CoDomain
的组合是单射的。尽管如此,有没有办法教授 GHC?我想象一些情况会根据 IsBase
谓词进行拆分。
将 Currying
改为由 func
索引对您来说会更好吗?
class Currying func where
curries :: (Products (Domains func) -> CoDomain func) -> func
uncurries :: func -> Products (Domains func) -> CoDomain func
instance Currying b => Currying (a -> b) where
curries f a = curries (f . (,) a)
uncurries f (a, as) = uncurries (f a) as
instance {-# OVERLAPPABLE #-} (IsBase b ~ 'True) => Currying b where
curries f = f ()
uncurries b _ = b
我们也可以用这种方式断言公理,虽然我什至不确定这个是否安全:
arrowAxiom :: forall func. func :~: Arrows (Domains func) (CoDomain func)
arrowAxiom = unsafeCoerce Refl
等式可以通过公理上的模式匹配放在范围内。
考虑 Arrows
、Domains
和 CoDomain
类型族定义 in the agda
codebase。
对于程序员来说很明显,它认为Arrows (Domains func) (CoDomain func) ~ func
。但是我无法通过 GHC 的类型检查器获得 curries (Proxy :: Proxy (Domains func)) (Proxy :: Proxy (CoDomain func)) undefined :: func
。这是因为 GHC 不够聪明,无法推断 Domains
和 CoDomain
的组合是单射的。尽管如此,有没有办法教授 GHC?我想象一些情况会根据 IsBase
谓词进行拆分。
将 Currying
改为由 func
索引对您来说会更好吗?
class Currying func where
curries :: (Products (Domains func) -> CoDomain func) -> func
uncurries :: func -> Products (Domains func) -> CoDomain func
instance Currying b => Currying (a -> b) where
curries f a = curries (f . (,) a)
uncurries f (a, as) = uncurries (f a) as
instance {-# OVERLAPPABLE #-} (IsBase b ~ 'True) => Currying b where
curries f = f ()
uncurries b _ = b
我们也可以用这种方式断言公理,虽然我什至不确定这个是否安全:
arrowAxiom :: forall func. func :~: Arrows (Domains func) (CoDomain func)
arrowAxiom = unsafeCoerce Refl
等式可以通过公理上的模式匹配放在范围内。