Commit d97e60f5 by dfordivam Committed by Ben Gamari

Reviewers: austin, bgamari

Reviewed By: bgamari

Subscribers: thomie

Differential Revision: https://phabricator.haskell.org/D1145
parent 18a15679
 ... @@ -36,7 +36,7 @@ This module performs checks about if one list of equations are: ... @@ -36,7 +36,7 @@ This module performs checks about if one list of equations are: \item Overlapped \item Overlapped \item Non exhaustive \item Non exhaustive \end{itemize} \end{itemize} To discover that we go through the list of equations in a tree-like fashion. To discover this we go through the list of equations in a tree-like fashion. If you like theory, a similar algorithm is described in: If you like theory, a similar algorithm is described in: \begin{quotation} \begin{quotation} ... @@ -55,10 +55,10 @@ The algorithm is based on the first technique, but there are some differences: ... @@ -55,10 +55,10 @@ The algorithm is based on the first technique, but there are some differences: (By the way the second technique is really similar to the one used in (By the way the second technique is really similar to the one used in @Match.hs@ to generate code) @Match.hs@ to generate code) This function takes the equations of a pattern and returns: The @check@ function takes the equations of a pattern and returns: \begin{itemize} \begin{itemize} \item The patterns that are not recognized \item The patterns that are not recognized \item The equations that are not overlapped \item The equations that are shadowed or overlapped \end{itemize} \end{itemize} It simplify the patterns and then call @check'@ (the same semantics), and it It simplify the patterns and then call @check'@ (the same semantics), and it needs to reconstruct the patterns again .... needs to reconstruct the patterns again .... ... @@ -74,7 +74,7 @@ then all the constructors are equal: ... @@ -74,7 +74,7 @@ then all the constructors are equal: f (: x (: y [])) = .... f (: x (: y [])) = .... f (: x xs) = ..... f (: x xs) = ..... \end{verbatim} \end{verbatim} (more about that in @tidy_eqns@) (more about this in @tidy_eqns@) We would prefer to have a @WarningPat@ of type @String@, but Strings and the We would prefer to have a @WarningPat@ of type @String@, but Strings and the Pretty Printer are not friends. Pretty Printer are not friends. ... @@ -175,26 +175,26 @@ untidy_lit (HsCharPrim src c) = HsChar src c ... @@ -175,26 +175,26 @@ untidy_lit (HsCharPrim src c) = HsChar src c untidy_lit lit = lit untidy_lit lit = lit {- {- This equation is the same that check, the only difference is that the @check@ is the external interface, boring work (tidy, untidy) is done boring work is done, that work needs to be done only once, this is in this as it needs to be done only once. the reason top have two functions, check is the external interface, @check'@ is called recursively, this is the reason to have two functions. @check'@ is called recursively. There are several cases: These are the several cases handled in @check'@: \begin{itemize} \begin{itemize} \item There are no equations: Everything is OK. \item There are no equations: Everything is OK. \item There are only one equation, that can fail, and all the patterns are \item If all the patterns are variables and the match can't fail then this equation is used and it doesn't generate non-exhaustive cases. \item There is only one equation that can fail, and all the patterns are variables. Then that equation is used and the same equation is variables. Then that equation is used and the same equation is non-exhaustive. non-exhaustive. \item All the patterns are variables, and the match can fail, there are \item All the patterns are variables, and the match can fail, there are more equations then the results is the result of the rest of equations more equations then the results is the result of the rest of equations and this equation is used also. and this equation is used also. \item The general case, if all the patterns are variables (here the match can't fail) then the result is that this equation is used and this equation doesn't generate non-exhaustive cases. \item In the general case, there can exist literals ,constructors or only \item In the general case, there can exist literals ,constructors or only vars in the first column, we actuate in consequence. vars in the first column, we actuate in consequence. ... @@ -330,7 +330,7 @@ This equation takes a matrix of patterns and split the equations by ... @@ -330,7 +330,7 @@ This equation takes a matrix of patterns and split the equations by constructor, using all the constructors that appears in the first column constructor, using all the constructors that appears in the first column of the pattern matching. of the pattern matching. We can need a default clause or not ...., it depends if we used all the Whether we need a default clause or not depends if we used all the constructors or not explicitly. The reasoning is similar to @process_literals@, constructors or not explicitly. The reasoning is similar to @process_literals@, the difference is that here the default case is not always needed. the difference is that here the default case is not always needed. -} -} ... @@ -363,7 +363,7 @@ construct_matrix con qs = ... @@ -363,7 +363,7 @@ construct_matrix con qs = (pats,indexs) = (check' (remove_first_column con qs)) (pats,indexs) = (check' (remove_first_column con qs)) {- {- Here remove first column is more difficult that with literals due to the fact Here removing the first column is more difficult (than literals) due to the fact that constructors can have arguments. that constructors can have arguments. For instance, the matrix For instance, the matrix ... @@ -531,8 +531,8 @@ is_var_lit lit pat ... @@ -531,8 +531,8 @@ is_var_lit lit pat {- {- The difference beteewn @make_con@ and @make_whole_con@ is that The difference beteewn @make_con@ and @make_whole_con@ is that @make_wole_con@ creates a new constructor with all their arguments, and @make_whole_con@ creates a new constructor with all their arguments, and @make_con@ takes a list of argumntes, creates the contructor getting their @make_con@ takes a list of arguments, creates the constructor getting their arguments from the list. See where \fbox{\ ???\ } are used for details. arguments from the list. See where \fbox{\ ???\ } are used for details. We need to reconstruct the patterns (make the constructors infix and We need to reconstruct the patterns (make the constructors infix and ... @@ -563,7 +563,7 @@ In particular: ... @@ -563,7 +563,7 @@ In particular: \\ @(x:(...:[])@ & returns to be & @[x,...]@ \\ @(x:(...:[])@ & returns to be & @[x,...]@ \end{tabular} \end{tabular} The difficult case is the third one becouse we need to follow all the The difficult case is the third one because we need to follow all the contructors until the @[]@ to know that we need to use the second case, contructors until the @[]@ to know that we need to use the second case, not the second. \fbox{\ ???\ } not the second. \fbox{\ ???\ } -} -} ... @@ -648,8 +648,8 @@ tidy_eqn eqn = eqn { eqn_pats = map tidy_pat (eqn_pats eqn), ... @@ -648,8 +648,8 @@ tidy_eqn eqn = eqn { eqn_pats = map tidy_pat (eqn_pats eqn), -------------- -------------- might_fail_pat :: Pat Id -> Bool might_fail_pat :: Pat Id -> Bool -- Returns True of patterns that might fail (i.e. fall through) in a way -- Returns True for patterns that might fail -- that is not covered by the checking algorithm. Specifically: -- (that are not covered by the checking algorithm) Specifically: -- NPlusKPat -- NPlusKPat -- ViewPat (if refutable) -- ViewPat (if refutable) -- ConPatOut of a PatSynCon -- ConPatOut of a PatSynCon ... @@ -670,7 +670,8 @@ might_fail_pat (BangPat p) = might_fail_lpat p ... @@ -670,7 +670,8 @@ might_fail_pat (BangPat p) = might_fail_lpat p might_fail_pat (ConPatOut { pat_con = con, pat_args = ps }) might_fail_pat (ConPatOut { pat_con = con, pat_args = ps }) = case unLoc con of = case unLoc con of RealDataCon _dcon -> any might_fail_lpat (hsConPatArgs ps) RealDataCon _dcon -> any might_fail_lpat (hsConPatArgs ps) PatSynCon _psyn -> True PatSynCon _psyn -> True -- This is considered 'might fail', as pattern synonym -- is not supported by checking algorithm -- Finally the ones that are sure to succeed, or which are covered by the checking algorithm -- Finally the ones that are sure to succeed, or which are covered by the checking algorithm might_fail_pat (LazyPat _) = False -- Always succeeds might_fail_pat (LazyPat _) = False -- Always succeeds ... @@ -696,7 +697,7 @@ tidy_pat (AsPat _ p) = tidy_pat (unLoc p) ... @@ -696,7 +697,7 @@ tidy_pat (AsPat _ p) = tidy_pat (unLoc p) tidy_pat (SigPatOut p _) = tidy_pat (unLoc p) tidy_pat (SigPatOut p _) = tidy_pat (unLoc p) tidy_pat (CoPat _ pat _) = tidy_pat pat tidy_pat (CoPat _ pat _) = tidy_pat pat -- These two are might_fail patterns, so we map them to -- These are might_fail patterns, so we map them to -- WildPats. The might_fail_pat stuff arranges that the -- WildPats. The might_fail_pat stuff arranges that the -- guard says "this equation might fall through". -- guard says "this equation might fall through". tidy_pat (NPlusKPat id _ _ _) = WildPat (idType (unLoc id)) tidy_pat (NPlusKPat id _ _ _) = WildPat (idType (unLoc id)) ... ...
 ... @@ -289,7 +289,7 @@ That's where AbsBinds comes in. It looks like this: ... @@ -289,7 +289,7 @@ That's where AbsBinds comes in. It looks like this: AbsBinds { abs_tvs = [a] AbsBinds { abs_tvs = [a] , abs_exports = [ABE { abe_poly = M.reverse :: forall a. [a] -> [a], , abs_exports = [ABE { abe_poly = M.reverse :: forall a. [a] -> [a], , abe_mono = reverse :: a -> a}] , abe_mono = reverse :: [a] -> [a]}] , abs_binds = { reverse :: [a] -> [a] , abs_binds = { reverse :: [a] -> [a] = \xs -> case xs of = \xs -> case xs of [] -> [] [] -> [] ... ...
 ... @@ -38,7 +38,7 @@ identifying the specific keyword being captured. ... @@ -38,7 +38,7 @@ identifying the specific keyword being captured. So So > let X = 1 in 2 *x > let x = 1 in 2 *x would result in the AST element would result in the AST element ... ...
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!