推断类型相等的 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,其中也包含所有导入和语言扩展。
我正在尝试填补以下代码段中的漏洞
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,其中也包含所有导入和语言扩展。