Sto usando lente biblioteca di Edward Kmett per la prima volta, e la ricerca è piuttosto bello, ma mi sono imbattuto in un intoppo ...Come evitare l'uso di obiettivi con tipi esistenti?
La domanda a [1] spiega che quantificatori esistenziali interrompono makeLenses. Preferisco davvero usare un esistenziale con le lenti in qualche modo.
Come sfondo, ho la classe:
class (TextShow file, Eq file, Ord file, Typeable file) => File file where
fromAnyFile :: AnyFile -> Maybe file
fileType :: Simple Lens file FileType
path :: Simple Lens file Text.Text
provenance :: Simple Lens file Provenance
Per la domanda attuale, voglio avere il tipo:
data AnyFile = forall file . File file => AnyFile { _anyFileAnyFile :: File }
E io voglio essere in grado di scrivere qualcosa sulla falsariga di:
Questo non funziona, per la ragione spiegata in [1]. Se chiedo GHC per il debug di informazioni da parte di compilazione con -ddump-splices
, ottengo:
Haskell/Main.hs:1:1: Splicing declarations
makeLenses ''AnyFile ======> Haskell/Main.hs:59:1-20
La giunzione stessa è vuota, che indica a me che non le dichiarazioni sono prodotti da esso. Questa parte mi aspetto e capisco ora che ho letto [1].
Quello che mi piacerebbe sapere è come posso fare questo - cosa potrei fare per aggirare il problema? Cosa potrei fare per evitare di nuotare controcorrente su questo? Mi piacerebbe essere in grado di accedere a qualsiasi parte delle mie strutture attraverso un percorso di lenti composte, ma poiché ho campi in altri tipi con tipi come Set AnyFile
, non posso farlo a meno che non riesca ad accedere al contenuto di AnyFile
con un obiettivo.
[1] Existential quantifier silently disrupts Template Haskell (makeLenses). Why?
Solo per chi si chiede, quello che ho fatto è stato utilizzare il suggerimento di seguito; la definizione doveva essere 'lens (\ (AnyFile file) -> file) (valore \ _ -> AnyFile value)'. –