Ten kod kompilujący jest zminimalizowanym przykładem this code z odpowiedzi na this issue z syntactic-2.0. Używam również definicji sameModType
pochodzącej z sameNat
w Data.Type.Equality.Korzystanie z Type.Equality with PolyKinds
byłem korzystania z tego rozwiązania bez problemu, ale chciałbym, aby moduł q
być niby-polimorficzny, z konkretnym celem dokonywania Proxy (nat :: Nat)
tylko nat :: Nat
(a jednocześnie jest w stanie wykorzystać moduły E z rodzaju *
) .
{-# 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
Ale kiedy dodać rozszerzenie -XPolyKinds
z kodem powyżej, mam kilka błędów kompilacji:
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 }
nie wiem wystarczająco dużo o magia dzieje w równości typu umieć to naprawić. Wygląda na to, że większość omawianych rodzajów jest beznadziejnie poza zasięgiem, jeśli chodzi o możliwość egzekwowania ograniczeń, o które prosi GHC, ale nigdy wcześniej nie miałem takiego problemu z PolyKinds
. Co trzeba zmienić, aby kod skompilował się z PolyKinds
?
Wielki wyjaśnienie, dzięki! Być może ktoś inny będzie wiedział, co robić. – crockeea
Powodem, dla którego nie wiem, co zrobić, jest to, że jest to mały przykład pozbawiony motywacji (podobnie jak w innym przykładzie, z którym się łączyłeś). Musiałbym wiedzieć, dlaczego definiujesz 'ZqType' tak, jak go definiujesz, a także dlaczego uważasz, że potrzebujesz w tym przypadku odpowiedniego polimorfizmu, zanim będę mógł spróbować doradzić, jak to zrobić. – kosmikus
Twórca biblioteki zaproponował definicję 'ZqType' jako rozwiązanie do wykorzystania mojego typu' Zq' z biblioteką (to jest typu o nieskończonych możliwościach dla parametru fantomowego). Myślę, że 'ZqType' może się zmienić, moim zdaniem jest to, że musi mieć rodzaj' * -> * '. Funkcja 'typeEqSym' pochodzi z klasy samej biblioteki, więc jej typ jest stały (ale definicja może się zmienić). – crockeea