Domanda

Questo codice compila bene:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances,
  UndecidableInstances, FlexibleContexts, EmptyDataDecls, ScopedTypeVariables,
  TypeOperators, TypeSynonymInstances, TypeFamilies #-}
class Sel a s b where
  type Res a s b :: *

instance Sel a s b where
  type Res a s b = (s -> (b,s))

instance Sel a s (b->(c,a)) where
  type Res a s (b->(c,a)) = (b -> s -> (c,s))

, ma non appena aggiungo GHC R predicato fallisce:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances,
  UndecidableInstances, FlexibleContexts, EmptyDataDecls, ScopedTypeVariables,
  TypeOperators, TypeSynonymInstances, TypeFamilies #-}
class Sel a s b where
  type Res a s b :: *

instance Sel a s b where
  type Res a s b = (s -> (b,s))

class R a where
  type Rec a :: *
  cons :: a -> Rec a
  elim :: Rec a -> a
instance Sel a s (b->(c,Rec a)) where
  type Res a s (b->(c,Rec a)) = (b -> s -> (c,s))

lamentando che:

    Illegal type synonym family application in instance:
        b -> (c, Rec a)
    In the instance declaration for `Sel a s (b -> (c, Rec a))'

che cosa significa e (soprattutto) come posso risolvere il problema?

Grazie

È stato utile?

Soluzione

famiglie tipo sono a senso unico: è possibile espandere Rec a al suo tipo calcolata, ma non si può (unicamente) passare dal retro espansione Rec a. Questo rende le applicazioni di funzioni di tipo inadatto per esempio le firme, in quanto non potranno mai far scattare l'istanza per applicare.

Si potrebbe provare invece:

instance Rec a ~ reca => Sel a s (b->(c,reca))

Questo significa un'altra cosa: si dice qualsiasi funzione b -> (c, reca) è un esempio, e poi quando si è irrevocabilmente abbinate, i controlli del compilatore che Rec a ~ reca. Ma questo potrebbe essere abbastanza buono per fare mancanza nel tuo caso.

Altri suggerimenti

Rec non è un costruttore tipo; si tratta di una funzione di tipo. Forse si può utilizzare solo per il tipo di un valore di definizione di tipo, non in una dichiarazione di classe? Sto indovinando selvaggiamente qui; Non capisco tutte le regole per le famiglie tipo.

Non so come risolvere il problema, ma alcune cose da provare sono:

  • Sbarazzarsi di classe Sel e basta definire type family Res a s b :: *. Uso type instance al posto del meccanismo della classe.

  • E 'a malapena possibile che per fare il tipo Rec iniettiva utilizzando data aiuterà, ma io non la penso così.

  • Taglia di nuovo al più piccolo numero di estensioni del linguaggio che potrebbe lavoro che renderà più facile per gli altri per aiutarti, e potrebbe aiutare il compilatore pure.

Ciò significa che non ti è permesso di utilizzare tipo famiglie synomym quando si dichiara istanze di tipo. Vedere la sezione "le famiglie di tipo e le dichiarazioni di istanza" del manuale GHC.

L'unico modo per risolvere il problema è quello di refactoring in modo da non averne bisogno in qualche modo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top