disco-0.2: Functional programming language for teaching discrete math.
Copyrightdisco team and contributors
LicenseBSD-3-Clause
Maintainerbyorgey@gmail.com
Safe HaskellSafe-Inferred
LanguageHaskell2010

Disco.Exhaustiveness

Description

Entry point into the exhaustiveness checker. Converts information into a format the checker understands, then pretty prints the results of running it.

Synopsis

Documentation

checkClauses :: Members '[Fresh, Reader TyDefCtx, Output (Message ann), Embed IO] r => Name ATerm -> [Type] -> NonEmpty [APattern] -> Sem r () Source #

This exhaustiveness checking algorithm is based on the paper "Lower Your Guards: A Compositional Pattern-Match Coverage Checker": https://www.microsoft.com/en-us/research/uploads/prod/2020/03/lyg.pdf

Some simplifications were made to adapt the algorithm to suit Disco. The most notable change is that here we always generate (at most) 3 concrete examples of uncovered patterns, instead of finding the most general complete description of every uncovered input.

desugarMatch :: Members '[Fresh, Embed IO] r => TypedVar -> APattern -> Sem r [Guard] Source #

Convert a Disco APattern into a list of Guards which cover that pattern

These patterns are currently not handled: , APNeg --still need to handle rational case , APFrac --required for rationals? algebraic (probably will be eventually replaced anyway): , APAdd , APMul , APSub These (or some updated version of them) may be handled eventually, once updated arithmetic patterns are merged.

We treat unhandled patterns as if they are exhaustively matched against (aka, they are seen as wildcards by the checker). This necessarily results in some false negatives, but no false positives.

data Gdt where Source #

Constructors

Grhs :: Int -> Gdt 
Branch :: Gdt -> Gdt -> Gdt 
Guarded :: Guard -> Gdt -> Gdt 

Instances

Instances details
Show Gdt Source # 
Instance details

Defined in Disco.Exhaustiveness

Methods

showsPrec :: Int -> Gdt -> ShowS #

show :: Gdt -> String #

showList :: [Gdt] -> ShowS #

Eq Gdt Source # 
Instance details

Defined in Disco.Exhaustiveness

Methods

(==) :: Gdt -> Gdt -> Bool #

(/=) :: Gdt -> Gdt -> Bool #

newtype Literal Source #

Constructors

Literal (TypedVar, LitCond) 

data LitCond where Source #

Instances

Instances details
Show LitCond Source # 
Instance details

Defined in Disco.Exhaustiveness

Eq LitCond Source # 
Instance details

Defined in Disco.Exhaustiveness

Methods

(==) :: LitCond -> LitCond -> Bool #

(/=) :: LitCond -> LitCond -> Bool #

Ord LitCond Source # 
Instance details

Defined in Disco.Exhaustiveness

data Ant where Source #

Constructors

AGrhs :: [NormRefType] -> Int -> Ant 
ABranch :: Ant -> Ant -> Ant 

Instances

Instances details
Show Ant Source # 
Instance details

Defined in Disco.Exhaustiveness

Methods

showsPrec :: Int -> Ant -> ShowS #

show :: Ant -> String #

showList :: [Ant] -> ShowS #

data InhabPat where Source #

Constructors

IPIs :: DataCon -> [InhabPat] -> InhabPat 
IPNot :: [DataCon] -> InhabPat 

Instances

Instances details
Show InhabPat Source # 
Instance details

Defined in Disco.Exhaustiveness

Eq InhabPat Source # 
Instance details

Defined in Disco.Exhaustiveness

Ord InhabPat Source # 
Instance details

Defined in Disco.Exhaustiveness

data ExamplePat where Source #

Constructors

ExamplePat :: DataCon -> [ExamplePat] -> ExamplePat 

Instances

Instances details
Show ExamplePat Source # 
Instance details

Defined in Disco.Exhaustiveness

findPosExamples :: Members '[Fresh, Reader TyDefCtx] r => [NormRefType] -> [TypedVar] -> Sem r [[ExamplePat]] Source #

Less general version of the above inhabitant finding function returns a maximum of 3 possible args lists that haven't been matched against, as to not overwhelm new users of the language. This is essentially a DFS, and it has a bad habit of trying to build infinite lists whenever it can, so we give it a max depth of 32 If we reach 32 levels of nested dataconstructors in this language, it is pretty safe to assume we were chasing after an infinite structure