C'è uno strumento che può aiutarmi a prevenire questo tipo di errore?
No, ma potrebbe esserci.
Come sapete, la sintassi di registrazione genera automaticamente getter con lo stesso nome degli attributi definiti. Pertanto il codice
data Person = Adult { pName :: String}
| Kid { pName :: String
, pAge :: Int
} deriving Show
crea le funzioni pName :: Person -> String
e pAge :: Person -> Int
. Ora, supponi Haskell ha avuto sottotipizzazione. Se così fosse, allora Kid
potrebbe essere un sottotipo di Person
e pAge
potrebbe avere il tipo più appropriato Kid -> String
. Tuttavia, Haskell fa non ha sottotipo, e quindi non esiste il tipo Kid
.
Ora, dato che Person -> String
è il tipo più specifico che possiamo dare a pAge
, perché non avvisare che pAge
è una funzione parziale in fase di compilazione? Mi permetta di deviare le domande per riferimento all'esempio Elenco
data List a = Cons { head :: a, tail :: List a } | Empty
In questo esempio, head
e tail
sono funzioni parziali: i due componenti di una lista non vuota, ma (a causa della mancanza di sottotipo Haskell) di accesso senza senso nella lista vuota Quindi, perché nessun avviso di default? Bene, per impostazione predefinita, conosci il codice che hai scritto. Il compilatore non fornisce avvisi se si utilizza unsafePerformIO
, perché qui si è il programmatore, si prevede di utilizzare tali cose in modo responsabile.
Così tl; dr: se si desidera che l'avviso qui:
getAge :: Person -> Int
getAge p = pAge p
allora sei fuori di fortuna, perché il sistema di tipo non dispone di informazioni sufficienti per dedurre che questo è un problema.
Se si desidera che l'avviso qui:
data Person = Adult | Kid { pAge :: Int }
allora sono sicuro che sarebbe banale da implementare: basta verificare che un determinato campo esiste in alcuni costruttori ma non altri. Ma non prevedo che questo avvertimento sia ampiamente utile per tutti; alcuni potrebbero lamentarsi che sarebbe solo rumore.
Scommetto che la gente del GHC sarebbe disposta a mettere un avvertimento per questo. Dovresti presentare una richiesta di funzione su [Trac] (http://hackage.haskell.org/trac/ghc/newticket?type=feature+request)! –
Esiste un sentimento generale di insoddisfazione nei confronti di record nella loro forma attuale. Alcune persone stanno studiando alternative. Nel frattempo, i record dei costruttori multipli non sono raccomandati e dovrebbero essere un avvertimento :-) –
http://hackage.haskell.org/trac/ghc/ticket/7169 - potresti aggiungerti a cc. – sdcvvc