Как помочь GHC сделать вывод, что `Arrows (Domains func) (CoDomain func) ~ func`

Рассмотрим Arrows, Domains а также CoDomain семейства типов, определенные в agda кодовая база.

Для программиста очевидно, что Arrows (Domains func) (CoDomain func) ~ func, Но я не могу получить curries (Proxy :: Proxy (Domains func)) (Proxy :: Proxy (CoDomain func)) undefined :: func через GHC's type-checker. Это потому, что GHC не достаточно умен, чтобы сделать вывод, что комбинация Domains а также CoDomain инъективно Есть ли способ научить GHC тем не менее? Я представляю IsBase сказуемое.

1 ответ

Решение

Будет ли лучше для вас изменить 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

Равенство может быть введено в область действия путем сопоставления с образцом по аксиоме.

Другие вопросы по тегам