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?