推断类型相等的 if 和 else 的约束

Infer constraints for both if and else of type equality

我正在尝试填补以下代码段中的漏洞

import Data.Proxy
import GHC.TypeLits
import Data.Type.Equality
import Data.Type.Bool
import Unsafe.Coerce

ifThenElse :: forall (a :: Nat) (b :: Nat) x l r.
  (KnownNat a, KnownNat b, x ~ If (a==b) l r) =>
  Proxy a -> Proxy b -> Either (x :~: l) (x :~: r)
ifThenElse pa pb = case sameNat pa pb of
  Just Refl -> Left Refl
  Nothing -> Right $ unsafeCoerce Refl -- This was the hole

可能吗?

编辑:检查了 sameNat 的来源,结果发现他们使用 unsafeCoerce。我相应地编辑了上面的代码。

一个可能的解决方案是使用 singletons 库来获取 term-level 代表 type-level 个(或 vice-versa)的函数。

它的要点是:

import Data.Singletons.Prelude

(...)

case (sing :: Sing a) %:== (sing :: Sing b) of
  STrue  -> Left Refl
  SFalse -> Right Refl

我已经发布了一个 self-contained file,其中也包含所有导入和语言扩展。