Diciamo che ho il seguente:"Sottoclasse" mostra in Haskell?
data Greek = Alpha | Beta | Gamma | Phi deriving Show
voglio usare la proiezione di default di tutti gli elementi tranne Beta, che voglio dire "due".
Posso fare questo?
Diciamo che ho il seguente:"Sottoclasse" mostra in Haskell?
data Greek = Alpha | Beta | Gamma | Phi deriving Show
voglio usare la proiezione di default di tutti gli elementi tranne Beta, che voglio dire "due".
Posso fare questo?
Per quanto ne so, non è possibile. Il meccanismo derivante non supporta comunque l'alterazione o l'estensione delle istanze derivate.
deriving Show
utilizza il meccanismo di istanziazione standard (semplicemente restituendo la definizione). Se si desidera che qualsiasi cose particolari, si dovrà istanziare manualmente:
data Greek = Alpha | Beta | Gamma | Phi
instance Show Greek
where
show Alpha = "Alpha"
show Beta = "2"
show Gamma = "Gamma"
show Phi = "Phi"
Non che questo è del tutto soddisfacente, ma si poteva fare:
data Greek = Alpha | Beta | Gamma | Phi
deriving (Show)
showGreek Beta = "2"
showGreek x = show x
E utilizzare showGreek al posto di spettacolo. Se avete bisogno di un'istanza di vero e proprio spettacolo (nel mio codice trovo che ho bisogno di questo a meno di principianti tendono a pensare), si potrebbe fare il piuttosto ingombrante:
newtype Greek' = Greek' Greek
instance Show Greek' where
show (Greek' g) = showGreek g
Se fosse il mio codice, che avevo appena bastone con showGreek
.
Una buona regola empirica che utilizzo è che le istanze Mostra e Lettura sono generate solo da Haskell. Se show non produce codice Haskell valido, non dovrebbe essere in un'istanza Show.
Non è corretto. Show non ha lo scopo di produrre codice Haskell, ma ha lo scopo di restituire una rappresentazione di stringa di un dato tipo di dati. In questo contesto, fintanto che Show and Read funzionano correttamente tra loro, non c'è davvero alcun problema a definire qualsiasi cosa si desideri. Anche l'uso di una nuova funzione 'showGreek' non è di grande aiuto, poiché l'istanziazione ha lo scopo di fornire un livello astratto con cui tutti i tipi di dati possono lavorare. – poke
poke, sarei più propenso ad accettare il tuo reclamo sull'intenzione di Show se volessi fornire un riferimento. Per quanto riguarda il livello di astrazione, sei corretto. Non puoi 'showGreek' con funzioni che accettano un vincolo come Mostra a =>, solo quelli che accettano un HOF per la visualizzazione. Tuttavia, nella mia pratica, che ammetto non è uguale al tuo, è meno problematico di quanto sembri.Se ci si imbatte in esso, "Greek" dovrebbe fare. E se non accetti la soluzione "greca", allora suppongo che dovrai accettare questo come una limitazione di Haskell o passare ad un'altra lingua :-P. – luqui
'base' contiene alcune istanze' Show' che non producono codice Haskell valido (come 'StdGen'). Generalmente è una buona idea far sì che 'show' produca un codice Haskell valido, ma non è obbligatorio. –
Alcuni degli altri suggerimenti funzionano bene nel tuo esempio particolare e suggerirei di utilizzarli.
Ma in un caso più generale, è possibile utilizzare datatype-generic programming.
Utilizzando la programmazione generica, è possibile scrivere funzioni che funzionano su più tipi di dati, ovvero funzioni che fanno lo stesso per ogni tipo di dati. Esempi di tali funzioni sono show
e ==
(questo è il motivo per cui questi possono essere derivati in GHC).
Questo è un esempio che utilizza la libreria regular:
{-# LANGUAGE TemplateHaskell, EmptyDataDecls, TypeFamilies #-}
import Generics.Regular
import qualified Generics.Regular.Functions.Show as G
data Greek = Alpha | Beta | Gamma | Phi
-- These two lines are all that is needed to use
-- Regulars generic functions on the 'Greek' data type.
$(deriveAll ''Greek "PFGreek")
type instance PF Greek = PFGreek
-- Manual written instance for 'Show'
instance Show Greek where
show Beta = "Two"
show x = G.show x -- Use Regulars 'show' for the boring parts
Per essere onesti, non mi piace molto l'uscita dal Regolari show
funzione (si getta in un ulteriore set di parentesi). Ma questo potrebbe essere un buon punto di partenza per scrivere le tue funzioni generiche.
Non risposta: 'myShow Beta =" Due "; myShow z = show z' – kennytm
Questa non è una non risposta. Questa è un'ottima risposta. :-) – Martijn