在 GHC Haskell 中,
Map k v
有一个 type role 声明,使 k
是名义上的。这是因为用户可以通过其他方式将 coerce
k
转换为具有相同表示但不同 Ord
实例的另一种类型,从而破坏不变量。
但是,我有一些新类型,其
Ord
实例是继承的。在这种情况下, unsafeCoerce
似乎可以完成这项工作(如果有我不知道的微妙之处,请纠正我),但这完全关闭了强制类型检查,这让我彻夜难眠。在我的具体用例中,我有一个类型 MyWrapper k
,并且我希望能够声明一些新类型 k1
-> k2
作为安全强制转换的可接受类型,即使它是 MyWrapper
的参数。这可能吗?还有哪些其他解决方法?
我想说为此特定目的引入类型类是有意义的。不实际进行转换,只是为
unsafeCoerce
的版本起别名,仅限于实际上安全的情况。
{-# LANGUAGE MultiParamTypeClasses #-}
class (Ord a, Ord b) => CompatibleOrd a b
-- no methods
instance CompatibleOrd YourBaseType YourNewtype
coerceKeysMonotonically :: (Coercible a b, CompatibleOrd a b)
=> Map a y -> Map b y
coerceKeysMonotonically = unsafeCoerce