Implement dependencyAnalysis

This commit is contained in:
Chris Done 2017-12-18 11:10:56 +00:00
parent f9317b857c
commit 477e5d103f

View File

@ -52,6 +52,8 @@ module Duet.Infer
import Control.Arrow (first,second) import Control.Arrow (first,second)
import Control.Monad.Catch import Control.Monad.Catch
import Control.Monad.State import Control.Monad.State
import Data.Generics
import Data.Graph
import Data.List import Data.List
import Data.Map.Strict (Map) import Data.Map.Strict (Map)
import qualified Data.Map.Strict as M import qualified Data.Map.Strict as M
@ -76,7 +78,7 @@ import Duet.Types
-- --
-- Throws 'InferException' in case of a type error. -- Throws 'InferException' in case of a type error.
typeCheckModule :: typeCheckModule ::
(MonadThrow m, Show l) (MonadThrow m, Show l, Data l)
=> Map Name (Class Type Name l) -- ^ Set of defined type-classes. => Map Name (Class Type Name l) -- ^ Set of defined type-classes.
-> [(TypeSignature Type Name Name)] -- ^ Pre-defined type signatures e.g. for built-ins or FFI. -> [(TypeSignature Type Name Name)] -- ^ Pre-defined type signatures e.g. for built-ins or FFI.
-> SpecialTypes Name -- ^ Special types that Haskell uses for pattern matching and literals. -> SpecialTypes Name -- ^ Special types that Haskell uses for pattern matching and literals.
@ -104,8 +106,38 @@ typeCheckModule ce as specialTypes bgs0 = do
-- | Sort the list of bindings by order of no-dependencies first -- | Sort the list of bindings by order of no-dependencies first
-- followed by things that depend on them. Group bindings that are -- followed by things that depend on them. Group bindings that are
-- mutually recursive. -- mutually recursive.
dependencyAnalysis :: [Binding t Name l] -> [BindGroup t Name l] dependencyAnalysis :: Data l => [Binding Type Name l] -> [BindGroup Type Name l]
dependencyAnalysis = undefined dependencyAnalysis = map toBindGroup . stronglyConnComp . bindingsGraph
where
toBindGroup =
\case
AcyclicSCC binding ->
BindGroup (explicits [binding]) [implicits [binding]]
CyclicSCC bindings ->
BindGroup (explicits bindings) [implicits bindings]
explicits =
mapMaybe
(\case
ExplicitBinding i -> Just i
_ -> Nothing)
implicits =
mapMaybe
(\case
ImplicitBinding i -> Just i
_ -> Nothing)
-- | Make a graph of the bindings with their dependencies.
bindingsGraph :: Data l => [Binding Type Name l] -> [(Binding Type Name l, Name, [Name])]
bindingsGraph =
map
(\binding ->
( binding
, bindingIdentifier binding
, listify
(\case
n@ValueName {} -> n /= bindingIdentifier binding
_ -> False)
(bindingAlternatives binding)))
collectMethods collectMethods
:: MonadThrow m :: MonadThrow m