Diciamo che ho la classe:classe Generalizzando Parametri
class C a b t where
f :: (a, b) -> (t a, t b)
Ora, con questa definizione, posso definire le istanze per dire:
(a,b) -> (Maybe a, Maybe b)
(a,b) -> ([a], [b])
Ma non per (per quanto ho capito):
(a,b) -> (a,b)
(a,b) -> ((a, a), (b, b))
ho potuto invece cambiare la mia definizione di classe in questo modo:
type family T a b x
class C a b where
f :: (a, b) -> (T a b a, T a b b)
che mi permettesse di fare quanto sopra, ma poi mi piacerebbe solo essere in grado di dichiarare una f
per ogni a
e b
.
Fondamentalmente voglio essere in grado di passare una famiglia di tipi come t
nella definizione originale, che è implicitamente risolta dal correttore di tipi se noto. Non voglio semplicemente renderlo f :: (a, b) -> (c, d)
perché voglio mantenere invariato che sia a
sia abbiano la stessa cosa fatta a loro, quindi swap . f
è lo stesso tipo di f . swap
. Sto pensando che potrebbe essere necessario injective type families (da GHC 8.0) ma non ne sono sicuro. Ma forse c'è un altro modo?
Una non risposta: è possibile utilizzare 'Identity' nel primo caso e un newtype appropriato nel secondo (non mi viene in mente nessuno standard al momento). Questa è una soluzione approssimativa, ma potrebbe rivelarsi meno doloroso rispetto al trucco avanzato che questo sembra richiedere. A proposito, il "Io non voglio solo renderlo" f :: (a, b) -> (c, d) 'come voglio mantenere l'invariante ..." suona molto come il problema di * gli obiettivi * lenti sono 'Lens stab' [anche se i quattro parametri sono mutuamente dipendenti] (http://comonad.com/reader/2012/mirrored-lenses) (vedere la sezione" Perché è una famiglia di obiettivi? "di il post). – duplode
Penso che questa sia fondamentalmente la stessa domanda di http://stackoverflow.com/questions/4922560/why-doesnt-typesynonyminstances-allow-partially-applied-type-synonyms-to-be-use –