Этот код компиляции представляет собой свернутый пример этого кода из ответа на эта проблема с syntactic-2.0. Я также использую определение sameModType
, полученное из sameNat
в Data.Type.Equality.
Я использовал это решение без проблем, но я хотел бы, чтобы модуль q
был полиморфным, с конкретной целью сделать Proxy (nat :: Nat)
просто nat :: Nat
(при этом можно было использовать модули вида *
).
{-# LANGUAGE GADTs,
MultiParamTypeClasses,
FunctionalDependencies,
FlexibleContexts,
FlexibleInstances,
TypeOperators,
ScopedTypeVariables,
DataKinds,
KindSignatures #-}
import Data.Tagged
import Data.Proxy
import Data.Type.Equality
import Data.Constraint
import Unsafe.Coerce
import GHC.TypeLits
newtype Zq q i = Zq i
data ZqType q
where
ZqType :: (Modulus q Int) => Proxy q -> ZqType (Zq q Int)
class (Integral i) => Modulus a i | a -> i where
value :: Tagged a i
instance (KnownNat q) => Modulus (Proxy (q :: Nat)) Int where
value = Tagged $ fromIntegral $ natVal (Proxy :: Proxy q)
sameModType :: (Modulus p i, Modulus q i)
=> Proxy p -> Proxy q -> Maybe (p :~: q)
sameModType p q | (proxy value p) == (proxy value q) =
Just $ unsafeCoerce Refl
| otherwise = Nothing
typeEqSym :: ZqType p -> ZqType q -> Maybe (Dict (p ~ q))
typeEqSym (ZqType p) (ZqType q) = do
Refl <- sameModType p q -- LINE 39
return Dict -- LINE 40
Но когда я добавляю расширение -XPolyKinds
к приведенному выше коду, я получаю несколько ошибок компиляции:
Foo.hs:39:36:
Could not deduce (k1 ~ k)
...
Expected type: Proxy q0
Actual type: Proxy q2
Relevant bindings include
q :: Proxy q2 (bound at Foo.hs:38:30)
p :: Proxy q1 (bound at Foo.hs:38:19)
In the second argument of ‘sameFactoredType’, namely ‘q’
In a stmt of a 'do' block: Refl <- sameFactoredType p q
Foo.hs:40:16:
Could not deduce (k ~ k1)
...
Relevant bindings include
q :: Proxy q2 (bound at Foo.hs:38:30)
p :: Proxy q1 (bound at Foo.hs:38:19)
In the first argument of ‘return’, namely ‘Dict’
In a stmt of a 'do' block: return Dict
In the expression:
do { Refl <- sameFactoredType p q;
return Dict }
Foo.hs:40:16:
Could not deduce (q1 ~ q2)
...
Relevant bindings include
q :: Proxy q2 (bound at Foo.hs:38:30)
p :: Proxy q1 (bound at Foo.hs:38:19)
In the first argument of ‘return’, namely ‘Dict’
In a stmt of a 'do' block: return Dict
In the expression:
do { Refl <- sameFactoredType p q;
return Dict }
Я недостаточно знаю о магии, происходящей в равенстве типов, чтобы знать, как это исправить. Похоже, что большинство рассматриваемых типов безнадежно выходят за рамки с точки зрения возможности обеспечения соблюдения ограничений, которые запрашивает GHC, но у меня никогда раньше не было таких проблем с PolyKinds
. Что нужно изменить, чтобы код компилировался с помощью PolyKinds
?