强制转换 newtyped reader monad 对其值类型进行强制转换
Coercion of newtyped reader monad given coercion for its value type
具有关联数据族 X
的类型类 C
需要一个函数 coerceX
。如果我像下面这样实现类型类,我该如何写 coerceX
?
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeApplications #-}
import Data.Type.Coercion
import Control.Monad.Reader
data (T r t)
class C t where
data X t :: * -> *
coerceX :: Coercion a b -> Coercion (X t a) (X t b)
instance (C t) => C (T r t) where
newtype X (T r t) a = X (Reader r (X t a))
coerceX = ...
您可以使用构造函数 Coercion
进行模式匹配,并为新值使用相同的构造函数 Coercion
。模式匹配将在范围内引入约束 Coercible a b
,并且对结果使用 Coercion
将使用该约束来证明想要的 Coercible (X (T r) a) (X (T r) b)
.
从实用的角度来说,这可以编译。神奇的事情发生在最后一行,编译器自动推断带入作用域的约束,以及结果类型检查所需的约束。然后编译器验证假设的约束确实暗示了要求的约束,对于 data X (T r) a
.
的给定定义
{-# LANGUAGE TypeFamilies #-}
import Data.Type.Coercion
import Control.Monad.Trans.Reader
class C t where
data X t :: * -> *
coerceX :: Coercion a b -> Coercion (X t a) (X t b)
data T r = Unused
instance C (T r) where
newtype X (T r) a = X (Reader r a)
coerceX Coercion = Coercion
写完上面的答案后问题变了。
对于更新后的问题,我认为我们需要一个量化约束来进行类型检查:
instance
(forall a b . Coercible a b
=> Coercible (X (T r t) a) (X (T r t) b))
=> C (T r t) where
newtype X (T r t) a = X (Reader r (X t a))
coerceX :: Coercion a b -> Coercion (X (T r t) a) (X (T r t) b)
coerceX Coercion = Coercion
我不确定以后会如何使用它。
看起来你可以通过必要的强制手段牵着鼻子走 GHC,就像这样:
{-# LANGUAGE InstanceSigs #-}
instance (C t) => C (T r t) where
newtype X (T r t) a = X (Reader r (X t a))
coerceX :: forall a b. Coercion a b -> Coercion (X (T r t) a) (X (T r t) b)
coerceX Coercion
= gcoerceWith (coerceX Coercion :: Coercion (X t a) (X t b)) $
(Coercion :: Coercion (X (T r t) a) (Reader r (X t a))) `trans`
(Coercion :: Coercible a' b' => Coercion (Reader r a') (Reader r b')) `trans`
(Coercion :: Coercion (Reader r (X t b)) (X (T r t) b))
一旦模式匹配:
coerceX Coercion = ...
将 Coercible a b
引入范围,我认为您需要为 C t
实例显式调用 coerceX
以获得 Coercion (X t a) (X t b)
。我不明白 GHC 如何自动推断出这一点。
现在,在一个理想的世界里,这样写就足够了:
coerceX Coercion = gcoerceWith (coerceX Coercion :: Coercion (X t a) (X t b)) Coercion
并且在 Coercible (X t a) (X t b)
范围内,GHC 将能够推断出 Reader r (X t a)
和 Reader r (X t b)
的表示相等性,从而推断出 X (T r t) a
和 [= 的表示相等性21=],但它无法实现这一飞跃。
具有关联数据族 X
的类型类 C
需要一个函数 coerceX
。如果我像下面这样实现类型类,我该如何写 coerceX
?
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeApplications #-}
import Data.Type.Coercion
import Control.Monad.Reader
data (T r t)
class C t where
data X t :: * -> *
coerceX :: Coercion a b -> Coercion (X t a) (X t b)
instance (C t) => C (T r t) where
newtype X (T r t) a = X (Reader r (X t a))
coerceX = ...
您可以使用构造函数 Coercion
进行模式匹配,并为新值使用相同的构造函数 Coercion
。模式匹配将在范围内引入约束 Coercible a b
,并且对结果使用 Coercion
将使用该约束来证明想要的 Coercible (X (T r) a) (X (T r) b)
.
从实用的角度来说,这可以编译。神奇的事情发生在最后一行,编译器自动推断带入作用域的约束,以及结果类型检查所需的约束。然后编译器验证假设的约束确实暗示了要求的约束,对于 data X (T r) a
.
{-# LANGUAGE TypeFamilies #-}
import Data.Type.Coercion
import Control.Monad.Trans.Reader
class C t where
data X t :: * -> *
coerceX :: Coercion a b -> Coercion (X t a) (X t b)
data T r = Unused
instance C (T r) where
newtype X (T r) a = X (Reader r a)
coerceX Coercion = Coercion
写完上面的答案后问题变了。
对于更新后的问题,我认为我们需要一个量化约束来进行类型检查:
instance
(forall a b . Coercible a b
=> Coercible (X (T r t) a) (X (T r t) b))
=> C (T r t) where
newtype X (T r t) a = X (Reader r (X t a))
coerceX :: Coercion a b -> Coercion (X (T r t) a) (X (T r t) b)
coerceX Coercion = Coercion
我不确定以后会如何使用它。
看起来你可以通过必要的强制手段牵着鼻子走 GHC,就像这样:
{-# LANGUAGE InstanceSigs #-}
instance (C t) => C (T r t) where
newtype X (T r t) a = X (Reader r (X t a))
coerceX :: forall a b. Coercion a b -> Coercion (X (T r t) a) (X (T r t) b)
coerceX Coercion
= gcoerceWith (coerceX Coercion :: Coercion (X t a) (X t b)) $
(Coercion :: Coercion (X (T r t) a) (Reader r (X t a))) `trans`
(Coercion :: Coercible a' b' => Coercion (Reader r a') (Reader r b')) `trans`
(Coercion :: Coercion (Reader r (X t b)) (X (T r t) b))
一旦模式匹配:
coerceX Coercion = ...
将 Coercible a b
引入范围,我认为您需要为 C t
实例显式调用 coerceX
以获得 Coercion (X t a) (X t b)
。我不明白 GHC 如何自动推断出这一点。
现在,在一个理想的世界里,这样写就足够了:
coerceX Coercion = gcoerceWith (coerceX Coercion :: Coercion (X t a) (X t b)) Coercion
并且在 Coercible (X t a) (X t b)
范围内,GHC 将能够推断出 Reader r (X t a)
和 Reader r (X t b)
的表示相等性,从而推断出 X (T r t) a
和 [= 的表示相等性21=],但它无法实现这一飞跃。