Supponiamo di avere un tipo di dati parametrizzato con più di un costruttore di dati null (costante), come ad esempio:
data Check a = Valid | Invalid | Unsure a
A volte voglio manipolare i costruttori non costanti con una funzione che mantiene fisse le costanti nulle e spero di farlo come
instance Functor Check where
fmap f (Unsure a) = Unsure (f a)
fmap f c = c
Questo fallisce nel typecheck perché nella dichiarazione fmap f c = c , se f :: a -> b allora c deve essere di entrambi i tipi Check a e Check b . Ovviamente potrei scriverlo completamente in
fmap f (Unsure a) = Unsure (f a)
fmap f Valid = Valid
fmap f Invalid = Invalid
che funziona ma diventa molto difficile quando ci sono molti costruttori nullari. Oppure, in alcuni casi potrei probabilmente ricavare istanze di Show e Read e usare read (show c) per forzare c al tipo necessario. Ma c'è un modo più elegante per avvicinarsi a questo?