considerare i seguenti tipi di dati e di pattern sinonimi:modelli Combinando
{-# LANGUAGE PatternSynonyms, NamedFieldPuns #-}
data Foo = Foo {
a :: Int
, b :: String
, c :: Maybe Bool
}
pattern Bar a b <- Foo { a, b }
pattern Baz c <- Foo { c }
mi piacerebbe abbinare una Foo
ma ottenere tutti a
, b
e c
. Qualcosa di simile (non valida Haskell):
showit :: Foo -> String
showit (Bar a b & Baz c) = show a ++ b ++ show c
Una possibilità è quella di utilizzare un ViewPattern
:
dup :: a -> (a, a)
dup a = (a, a)
showall' :: Foo -> String
showall' (dup -> (Bar a b, Baz c)) = show a ++ b ++ show c
Ma questo si traduce in un messaggio di avviso non esaustivo partita. Ma sappiamo che Bar
e Baz
sono inconfutabili, quindi anche l'abbinamento tra loro è inconfutabile.
Come può essere espresso senza un avvertimento del compilatore?
La motivazione consiste nel disporre di sinonimi di pattern a grana fine rispetto a campi di un tipo di dati di grandi dimensioni e consentire ai chiamanti di estrarre solo i campi desiderati simili ai record con NamedFieldPuns
. I sinonimi di pattern non supportano ancora la sintassi dei record, ma è in corso: https://ghc.haskell.org/trac/ghc/ticket/8582
Nel mio caso non posso esporre il costruttore dal modulo poiché sto usando il modello "smart-constructor", e quindi non posso dare i chiamanti il vantaggio del modello di registrazione corrispondente a NamedFieldPuns
.
Vedere https://stackoverflow.com/a/25161749/3198498 come ispirazione. Sto cercando di estendere l'idea in quella risposta per consentire ai chiamanti di estrarre arbitrariamente i campi n di m, per un numero maggiore m.
Edit: Sembra che v'è un piuttosto ampio problema con PatternSynonyms
e l'esaustività controlli: https://ghc.haskell.org/trac/ghc/ticket/10339 Questo sembra rendere i sinonimi di pattern utilizzati come estrattori di campo molto sgradevole quando si compila con gli avvisi attivati.
Questo probabilmente non è quello che vuoi, ma che dire: 'modello Barz a b c <- Foo {a b c}'? –
@ChristopherDumas - Spero di trovare una soluzione con un singolo pattern per campo, o un pattern con una sintassi simile a record usando nomi poiché Foo può avere 10 o più campi. La buona notizia è che il ticket 8582 è previsto per l'inclusione nella prossima versione di GHC, quindi dovremmo ottenere sinonimi di pattern con sintassi di registrazione quindi. – wrl