diff options
author | Richard Eisenberg <eir@cis.upenn.edu> | 2014-12-12 17:19:21 -0500 |
---|---|---|
committer | Richard Eisenberg <eir@cis.upenn.edu> | 2014-12-12 17:24:37 -0500 |
commit | 0cc47eb90805f3e166ac4d3991e66d3346ca05e7 (patch) | |
tree | 1ed6c6dd440e1dcdd32f16d547b3e0c4ceeddbda /compiler/utils | |
parent | 058262bac0bbcd65f40703bf8047238ffa30d2c3 (diff) | |
download | haskell-0cc47eb90805f3e166ac4d3991e66d3346ca05e7.tar.gz |
Rewrite `Coercible` solver
Summary:
This is a rewrite of the algorithm to solve for Coercible "instances".
A preliminary form of these ideas is at
https://ghc.haskell.org/trac/ghc/wiki/Design/NewCoercibleSolver
The basic idea here is that the `EqPred` constructor of `PredTree`
now is parameterised by a new type `EqRel` (where
`data EqRel = NomEq | ReprEq`). Thus, every equality constraint can
now talk about nominal equality (the usual case) or representational
equality (the `Coercible` case).
This is a change from the previous
behavior where `Coercible` was just considered a regular class with
a special case in `matchClassInst`.
Because of this change, representational equalities are now
canonicalized just like nominal ones, allowing more equalities
to be solved -- in particular, the case at the top of #9117.
A knock-on effect is that the flattener must be aware of the
choice of equality relation, because the inert set now stores
both representational inert equalities alongside the nominal
inert equalities. Of course, we can use representational equalities
to rewrite only within another representational equality --
thus the parameterization of the flattener.
A nice side effect of this change is that I've introduced a new
type `CtFlavour`, which tracks G vs. W vs. D, removing some ugliness
in the flattener.
This commit includes some refactoring as discussed on D546.
It also removes the ability of Deriveds to rewrite Deriveds.
This fixes bugs #9117 and #8984.
Reviewers: simonpj, austin, nomeata
Subscribers: carter, thomie
Differential Revision: https://phabricator.haskell.org/D546
GHC Trac Issues: #9117, #8984
Diffstat (limited to 'compiler/utils')
-rw-r--r-- | compiler/utils/MonadUtils.hs | 14 | ||||
-rw-r--r-- | compiler/utils/Util.hs | 11 |
2 files changed, 24 insertions, 1 deletions
diff --git a/compiler/utils/MonadUtils.hs b/compiler/utils/MonadUtils.hs index b066b404a1..edc863ab0c 100644 --- a/compiler/utils/MonadUtils.hs +++ b/compiler/utils/MonadUtils.hs @@ -11,7 +11,7 @@ module MonadUtils , liftIO1, liftIO2, liftIO3, liftIO4 - , zipWith3M + , zipWith3M, zipWith3M_, zipWithAndUnzipM , mapAndUnzipM, mapAndUnzip3M, mapAndUnzip4M , mapAccumLM , mapSndM @@ -71,6 +71,18 @@ zipWith3M f (x:xs) (y:ys) (z:zs) ; return $ r:rs } +zipWith3M_ :: Monad m => (a -> b -> c -> m d) -> [a] -> [b] -> [c] -> m () +zipWith3M_ f as bs cs = do { _ <- zipWith3M f as bs cs + ; return () } + +zipWithAndUnzipM :: Monad m + => (a -> b -> m (c, d)) -> [a] -> [b] -> m ([c], [d]) +zipWithAndUnzipM f (x:xs) (y:ys) + = do { (c, d) <- f x y + ; (cs, ds) <- zipWithAndUnzipM f xs ys + ; return (c:cs, d:ds) } +zipWithAndUnzipM _ _ _ = return ([], []) + -- | mapAndUnzipM for triples mapAndUnzip3M :: Monad m => (a -> m (b,c,d)) -> [a] -> m ([b],[c],[d]) mapAndUnzip3M _ [] = return ([],[],[]) diff --git a/compiler/utils/Util.hs b/compiler/utils/Util.hs index 7d44a5004b..aa3a19b64c 100644 --- a/compiler/utils/Util.hs +++ b/compiler/utils/Util.hs @@ -14,6 +14,8 @@ module Util ( zipEqual, zipWithEqual, zipWith3Equal, zipWith4Equal, zipLazy, stretchZipWith, zipWithAndUnzip, + filterByList, + unzipWith, mapFst, mapSnd, chkAppend, @@ -301,6 +303,15 @@ zipLazy :: [a] -> [b] -> [(a,b)] zipLazy [] _ = [] zipLazy (x:xs) ~(y:ys) = (x,y) : zipLazy xs ys +-- | 'filterByList' takes a list of Bools and a list of some elements and +-- filters out these elements for which the corresponding value in the list of +-- Bools is False. This function does not check whether the lists have equal +-- length. +filterByList :: [Bool] -> [a] -> [a] +filterByList (True:bs) (x:xs) = x : filterByList bs xs +filterByList (False:bs) (_:xs) = filterByList bs xs +filterByList _ _ = [] + stretchZipWith :: (a -> Bool) -> b -> (a->b->c) -> [a] -> [b] -> [c] -- ^ @stretchZipWith p z f xs ys@ stretches @ys@ by inserting @z@ in -- the places where @p@ returns @True@ |