Questo codice di compilazione è un esempio ridotto di this code da una risposta a this issue con sintattica-2.0. Sto anche usando una definizione di sameModType
derivata da sameNat
in Data.Type.Equality.Utilizzo di Type.Equality con PolyKinds
avevo usato questa soluzione senza problema, ma mi piacerebbe fare il modulo q
essere gentile-polimorfico, con l'obiettivo specifico di rendere Proxy (nat :: Nat)
ad appena nat :: Nat
(pur essendo in grado di utilizzare moduli di tipo *
) .
{-# 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
Ma quando aggiungo l'estensione -XPolyKinds
al codice di cui sopra, ottengo molti errori di compilazione:
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 }
Non conosco abbastanza la magia in corso nella uguaglianza tipo di sapere come per risolvere questo. Sembra che la maggior parte dei tipi in questione sia irrimediabilmente fuori dal campo di applicazione in termini di capacità di far rispettare i vincoli che GHC sta chiedendo, ma non ho mai avuto questo tipo di problema con PolyKinds
. Cosa deve essere modificato per compilare il codice con PolyKinds
?
Un grande spiegazione, grazie! Forse qualcun altro saprà cosa fare. – crockeea
La ragione per cui non so cosa fare è perché questo è un piccolo esempio che manca di motivazione (allo stesso modo dell'altro esempio a cui sei collegato). Dovrei sapere perché definisci 'ZqType' nel modo in cui lo definisci, e anche perché credi di aver bisogno di un polimorfismo gentile, in primo luogo, prima che potessi provare a dare consigli su come farlo funzionare. – kosmikus
Lo sviluppatore della libreria ha proposto quella definizione per 'ZqType' come soluzione per l'uso del mio tipo' Zq' con la libreria (cioè un tipo con infinite possibilità per un parametro fantasma). Penso che 'ZqType' potrebbe cambiare, la mia comprensione è che deve avere tipo' * -> * '. La funzione 'typeEqSym' proviene da una classe nella libreria stessa, quindi il suo tipo è fisso (ma la definizione può cambiare). – crockeea