[Haskell-cafe] Composing analyses.
Serguey Zefirov
sergueyz at gmail.com
Wed Jan 4 20:44:59 CET 2012
I am trying to create a stack of analyses. There are basic analyses
then there are derived analyses that create a DAG of analyses.
I thought I can express their relationship through type classes, but I
failed. I've attached the source of my failure.
Main points are below:
getAnalysisResult :: EnabledAnalysis a as => a -> M as Int
getAnalysisResult _ = error "getAnalysisResult!!!"
setAnalysisResult :: EnabledAnalysis a as => a -> Int -> M as ()
setAnalysisResult _ _ = error "setAnalysisResult!!!"
-- |Analysis interface. What to require and what to perform.
class (Analyses (RequiresAnalyses a)) => Analysis a where
-- |What has to be done before our pass.
type RequiresAnalyses a
-- |Perform an analysis.
perform :: (EnabledAnalysis a as, EnabledAnalyses (RequiresAnalyses a) as) =>
a -> M as ()
data AnalysisNotEnabled a
-- |Check if analysis is enabled.
class EnabledAnalysis a as
instance (FAIL (AnalysisNotEnabled a)) => EnabledAnalysis a Nil
instance (Analysis a, Analyses as) => EnabledAnalysis a (a :. as)
instance (Analysis a, Analysis a', EnabledAnalysis a as) =>
EnabledAnalysis a (a' :. as)
-- |Check if a group of analyses is enabled.
class EnabledAnalyses as eas
instance EnabledAnalyses Nil eas
instance (EnabledAnalyses as eas, EnabledAnalysis a eas) =>
EnabledAnalyses (a :. as) eas
-- Base analysis.
data Base = Base
instance Analysis Base where
type RequiresAnalyses Base = Nil
perform a = do
x <- getAnalysisResult a
setAnalysisResult a (x+1)
-- And analysis derived from Base.
data Derived = Derived
instance Analysis Derived where
type RequiresAnalyses Derived = Base :. Nil
-- !!! this is the source of problems
-- the type here is
-- (EnabledAnalysis Derived as, EnabledAnalyses (Base :. Nil) as) =>
-- Derived -> M as ()
-- Looks like ghc does not expand RequiresAnalyses Derived.
perform a = do
x <- getAnalysisResult a
y <- getAnalysisResult Base
setAnalysisResult a (x+y)
-- here I expanded RequiresAnalysis Derived manually.
-- ghc thinks that "EnabledAnalyses (Base :. Nil) as" does not imply
"EnableAnalysis Base as".
-- it is weird.
performDerived :: (EnabledAnalysis Derived as, EnabledAnalyses (Base
:. Nil) as) =>
Derived -> M as ()
performDerived a = do
x <- getAnalysisResult a
y <- getAnalysisResult Base
setAnalysisResult a (x+y)
This is behavior of ghc 6.12.1, 7.0.4 and 7.2.1. Is it right behavior?
The main question is: is it possible to combine computations like
this? How should one do this? I thinking about abandoning type classes
altogether. I think I can do it some other way. But out of curiosity -
why is that?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: a.hs
Type: application/octet-stream
Size: 2434 bytes
Desc: not available
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20120104/ddb5c092/attachment.obj>
More information about the Haskell-Cafe
mailing list