如果我有一个类型系列(关闭或打开,我对两者都感兴趣)
type family F a :: Constraint
以及F a
作为约束的函数,该函数在运行时的外观如何?字典是什么样的?
动机:
我试图使用来自reflection
的技巧从我的一个函数中丢弃一个不需要的约束,在某些情况下它可以工作,在其他情况下,我得到一个段错误,所以我正在寻找一个更有原则的接近而不是我的反复试验。
编辑:
这是一个有效的代码示例
import Data.Kind
import Unsafe.Coerce
type family Elem (x :: k) (xs :: [k]) :: Bool where
Elem x '[] = 'False
Elem x (x ': xs) = 'True
Elem x (y ': xs) = Elem x xs
type family IsSubset xs ys :: Constraint where
IsSubset '[] ys = ()
IsSubset (x ': xs) ys = (IsTrue (Elem x ys), IsSubset xs ys)
type IsTrue b = b ~ 'True
data Tagged l a = Tagged a deriving Show
g :: (Num a, IsSubset l1 l2) => Tagged l1 a -> Tagged l2 a -> Tagged l2 a
g (Tagged x) (Tagged y) = Tagged (x + y)
newtype Magic c a = Magic (c => a)
discard :: forall c a. (c => a) -> a
discard a = unsafeCoerce (Magic @c @a a) ()
f :: forall k l1 a. (Num a) => Tagged (l1 :: [k]) a -> Tagged l1 a -> Tagged l1 a
f = discard @(IsSubset l1 l1) g
并测试它:
> f (Tagged 1) (Tagged 2)
Tagged 3