Control.Exhaustive - Hackage
exhaustive is a library that guarantees that when building a parser, or some other computation that produces data, all possible constructors in a data type are considered. You can think of this library as providing a symmetry to GHC's built in -fwarn-incomplete-patterns compile time warning, although this library is stricter in that it produces compile time errors if a constructor is omitted.
Usage of this library is intended to be straightforward, though admittedly the types might have you think the opposite! To understand this library, an example may be helpful.
To begin with, consider a simple data type for a "boolean expressions" language:
import qualified GHC.Generics as GHC data Expr = ETrue | EFalse | EIf Expr Expr Expr deriving (Eq, GHC.Generic) instance Generic ExprNote that we have to make our data type an instance of both GHC.Generics.Generic and Generics.SOP.Generic, though this only requires boiler-plate code.
Next, we would like to build a parser for this language. Let's assume that we have access to a parsec-like library, where we have one basic combinator:
- symbol :: String -> Parser String
Ordinarily, we would write our parser as
parseExpr :: Parser Expr parseExpr = msum [ETrue <$ symbol "True" ,EFalse <$ symbol "False" ,EIf <$> symbol "if" *> parseExpr <*> symbol "then" *> parseExpr <*> symbol "else" *> parseExpr ]However, nothing is making sure that we actually considered all constructors in Expr. We could just as well write
parseExpr :: Parser Expr parseExpr = msum [ETrue <$ symbol "True" ,EFalse <$ symbol "False"]Although this is significantly less useful!
Using exhaustive, we can get exhaustivity checks that we are at least considering all constructors:
parseExpr :: Parser Expr parseExpr = produceFirst $ construct (\f -> f <$ symbol "True") :* construct (\f -> f <$ symbol "False") :* construct (\f -> f <$> symbol "if" *> parseExpr <*> symbol "then" *> parseExpr <*> symbol "else" *> parseExpr) :* NilAs you can hopefully see, exhaustive requires only minimal changes to an existing parser. Specifically, we need to:
- Use produceFirst instead of msum
- Wrap each constructor application with construct.
- Use the provided constructor function, rather than the named constructors in the original data type.
Từ khóa » H0 B0 M0
-
Habilitation électrique HO BO M0 - Sécurité - Formation Continue
-
ME – B0 – H0(V) – Exécutant Ou Chargé De Chantier – M0 - CODEV
-
M0 – Non Mécanicien, M1 – Exécutant – ME – Opérateur Chargé De ...
-
Habilitation Mécanique M0, M1 Et ME ((Manœuvre, Vérification Et ...
-
Formation E-learning M0 - H0V H0B0 - Groupe ACN
-
Préparation à L'habilitation B0-H0-M0 - NFC 18-510 - Anteres
-
Services - Solar With Huawei
-
H0 B0 M0 | WordReference Forums
-
Préparation à L'habilitation Mécanique Non Mécanicien M0
-
Parity_scale_codec::DecodeLength - Rust
-
A SPATIAL CHARACTERIZATION OF ω CONDITIONAL ... - Jstor