on master help sign in
Begin getting the parser to match the new SourceSyntax modules.
commit339ad77c46c94f2fc28cd2ab2ebe4500d70a15d9 authorevancz <info@elm-lang.org> dateThu 13 Jun 2013, 18:35 (13 years ago) parentbbb2b2a
12 files changed+75−218
compiler/Model/Guid.hs → compiler/Guid.hs compiler/Model/Ast.hs−156 compiler/Parse/Binops.hs+14−18 compiler/Parse/Expr.hs+9−8 compiler/Parse/Library.hs → compiler/Parse/Helpers.hs+9−9 compiler/Parse/Patterns.hs+1−1 compiler/Parse/Types.hs+8−7 compiler/SourceSyntax/Declaration.hs+4−1 compiler/Transform/Rename.hs → compiler/SourceSyntax/Rename.hs+12−7 compiler/Types/Solver.hs+13−8 compiler/Types/Types.hs+1−1 compiler/Types/Unify.hs+4−2
compiler/Model/Guid.hs → compiler/Guid.hsrenamed

The content is the same.

compiler/Model/Ast.hsdeleted−156
@@ -1,156 +0,0 @@
1−{-# LANGUAGE DeriveDataTypeable #-}
2−module Ast where
3−
4−import Located
5−import Data.Char (isDigit, isSymbol)
6−import Data.List (intercalate)
7−import Types.Types
8−import qualified Text.Pandoc as Pandoc
9−import Data.Data
10−
11−data Module = Module [String] Exports Imports [Statement]
12− deriving (Show)
13−
14−type Exports = [String]
15−
16−type Imports = [(String, ImportMethod)]
17−data ImportMethod = As String | Importing [String] | Hiding [String]
18− deriving (Eq, Ord, Show, Data, Typeable)
19−
20−
21−data Pattern = PData String [Pattern]
22− | PRecord [String]
23− | PAsVar String Pattern
24− | PVar String
25− | PAnything
26− deriving (Eq, Data, Typeable)
27−
28−type CExpr = Located Expr
29−data Expr = IntNum Int
30− | FloatNum Float
31− | Chr Char
32− | Str String
33− | Boolean Bool
34− | Range CExpr CExpr
35− | Access CExpr String
36− | Remove CExpr String
37− | Insert CExpr String CExpr
38− | Modify CExpr [(String,CExpr)]
39− | Record [(String,[String],CExpr)]
40− | Binop String CExpr CExpr
41− | Lambda String CExpr
42− | App CExpr CExpr
43− | MultiIf [(CExpr,CExpr)]
44− | Let [Def] CExpr
45− | Var String
46− | Case CExpr [(Pattern,CExpr)]
47− | Data String [CExpr]
48− | Markdown Pandoc.Pandoc
49− deriving (Eq, Data, Typeable)
50−
51−data Def = FnDef String [String] CExpr
52− | OpDef String String String CExpr
53− | TypeAnnotation String Type
54− deriving (Eq, Data, Typeable)
55−
56−data Statement = Definition Def
57− | Datatype String [X] [(String,[Type])]
58− | TypeAlias String [X] Type
59− | ImportEvent String CExpr String Type
60− | ExportEvent String String Type
61− deriving (Eq, Show, Data, Typeable)
62−
63−cons h t = epos h t (Data "Cons" [h,t])
64−nil = L (Just "[]") NoSpan (Data "Nil" [])
65−list = foldr cons nil
66−tuple es = Data ("Tuple" ++ show (length es)) es
67−
68−delist (L _ _ (Data "Cons" [h,t])) = h : delist t
69−delist _ = []
70−
71−
72−pcons h t = PData "Cons" [h,t]
73−pnil = PData "Nil" []
74−plist = foldr pcons pnil
75−ptuple es = PData ("Tuple" ++ show (length es)) es
76−
77−brkt s = "{ " ++ s ++ " }"
78−parensIf b s = if b then parens s else s
79−isOp c = isSymbol c || elem c "+-/*=.$<>:&|^?%#@~!"
80−
81−instance Show Pattern where
82− show p =
83− case p of
84− PRecord fs -> brkt (intercalate ", " fs)
85− PVar x -> x
86− PAsVar x p -> show p ++ " as " ++ x
87− PAnything -> "_"
88− PData "Cons" [hd@(PData "Cons" _),tl] ->
89− parens (show hd) ++ " :: " ++ show tl
90− PData "Cons" [hd,tl] -> show hd ++ " : " ++ show tl
91− PData "Nil" [] -> "[]"
92− PData name ps ->
93− if take 5 name == "Tuple" && all isDigit (drop 5 name) then
94− parens . intercalate ", " $ map show ps
95− else parensIf (not (null ps)) $ unwords (name : map show ps)
96−
97−instance Show Expr where
98− show e =
99− let show' (L _ _ e) = parensIf (needsParens e) (show e) in
100− case e of
101− IntNum n -> show n
102− FloatNum n -> show n
103− Chr c -> show c
104− Str s -> show s
105− Boolean b -> show b
106− Range e1 e2 -> "[" ++ show e1 ++ ".." ++ show e2 ++ "]"
107− Access e x -> show' e ++ "." ++ x
108− Remove e x -> brkt (show e ++ " - " ++ x)
109− Insert (L _ _ (Remove e y)) x v ->
110− brkt (show e ++ " - " ++ y ++ " | " ++ x ++ " = " ++ show v)
111− Insert e x v -> brkt (show e ++ " | " ++ x ++ " = " ++ show v)
112− Modify e fs -> brkt (show e ++" | "++ intercalate ", " (map field fs))
113− where field (x,e) = x ++ " <- " ++ show e
114− Record r -> brkt (intercalate ", " (map fields r))
115− where fields (f,args,e) = f ++ concatMap (' ':) args ++ " = " ++ show e
116− Binop op e1 e2 -> show' e1 ++ " " ++ op ++ " " ++ show' e2
117− Lambda x e -> let (xs,e') = getLambdas (notLocated $ Lambda x e) in
118− concat [ "\\", intercalate " " xs, " -> ", show e' ]
119− App e1 e2 -> show' e1 ++ " " ++ show' e2
120− MultiIf (p:ps) -> concat [ "if | ", iff p, sep (map iff ps) ]
121− where iff (b,e) = show b ++ " -> " ++ show e
122− sep = concatMap ("\n | " ++)
123− Let defs e -> "let { "++intercalate " ; " (map show defs)++" } in "++show e
124− Var (c:cs) -> if isOp c then parens (c:cs) else c:cs
125− Case e pats -> "case "++ show e ++" of " ++ brkt (intercalate " ; " pats')
126− where pats' = map (\(p,e) -> show p ++ " -> " ++ show e) pats
127− Data name es
128− | name == "Cons" -> ("["++) . (++"]") . intercalate "," . map show $
129− delist (notLocated $ Data "Cons" es)
130− | name == "Nil" -> "[]"
131− | otherwise -> name ++ " " ++ intercalate " " (map show' es)
132− Markdown _ -> "[markdown| ... |]"
133−
134−
135−instance Show Def where
136− show e =
137− case e of
138− FnDef v [] e -> v ++ " = " ++ show e
139− FnDef f args e -> f ++ concatMap (' ':) args ++ " = " ++ show e
140− OpDef op a1 a2 e -> intercalate " " [a1,op,a2] ++ " = " ++ show e
141− TypeAnnotation n t -> n ++ " : " ++ show t
142−
143−getLambdas (L _ _ (Lambda x e)) = (x:xs,e')
144− where (xs,e') = getLambdas e
145−getLambdas e = ([],e)
146−
147−needsParens e =
148− case e of
149− Binop _ _ _ -> True
150− Lambda _ _ -> True
151− App _ _ -> True
152− MultiIf _ -> True
153− Let _ _ -> True
154− Case _ _ -> True
155− Data name (x:xs) -> name /= "Cons"
156− _ -> False
compiler/Parse/Binops.hs+14−18
@@ -1,18 +1,14 @@
11module Parse.Binops (binops, infixStmt, OpTable) where
22
3−import Ast
4−import Control.Monad (liftM,guard)
53import Control.Monad.Error
6−import Data.List (foldl',splitAt,elemIndices
7− ,group,groupBy,sortBy,find,intercalate)
4+import Data.List (intercalate)
85import qualified Data.Map as Map
9−import Data.Maybe (mapMaybe)
106
11−import Located (epos)
7+import SourceSyntax.Location (merge)
8+import SourceSyntax.Expression (LExpr, Expr(Binop))
9+import SourceSyntax.Declaration (Assoc(..))
1210import Text.Parsec
13−import Parse.Library
14−
15−data Assoc = L | N | R deriving (Eq,Show)
11+import Parse.Helpers
1612
1713type OpTable = [(Int, Assoc, String)]
1814
@@ -39,10 +35,10 @@ opAssoc :: OpTable -> String -> Assoc
3935opAssoc table op = Map.findWithDefault R op dict
4036 where dict = Map.fromList (map (\(_,assoc,op) -> (op,assoc)) table)
4137
42−hasLevel :: OpTable -> Int -> (String,CExpr) -> Bool
38+hasLevel :: OpTable -> Int -> (String,LExpr) -> Bool
4339hasLevel table n (op,_) = opLevel table op == n
4440
45−binops :: OpTable -> IParser CExpr -> IParser String -> IParser CExpr
41+binops :: OpTable -> IParser LExpr -> IParser String -> IParser LExpr
4642binops table term anyOp =
4743 do e <- term
4844 split (table ++ preludeTable) 0 e =<< many nextOp
@@ -52,7 +48,7 @@ binops table term anyOp =
5248 whitespace ; e <- term
5349 return (op,e)
5450
55−split :: OpTable -> Int -> CExpr -> [(String, CExpr)] -> IParser CExpr
51+split :: OpTable -> Int -> LExpr -> [(String, LExpr)] -> IParser LExpr
5652split _ _ e [] = return e
5753split table n e eops = do
5854 assoc <- getAssoc table n eops
@@ -61,25 +57,25 @@ split table n e eops = do
6157 case assoc of R -> joinR es ops
6258 _ -> joinL es ops
6359
64−splitLevel :: OpTable -> Int -> CExpr -> [(String, CExpr)] -> [IParser CExpr]
60+splitLevel :: OpTable -> Int -> LExpr -> [(String, LExpr)] -> [IParser LExpr]
6561splitLevel table n e eops =
6662 case break (hasLevel table n) eops of
6763 (lops, (op,e'):rops) ->
6864 split table (n+1) e lops : splitLevel table n e' rops
6965 (lops, []) -> [ split table (n+1) e lops ]
7066
71−joinL :: [CExpr] -> [String] -> IParser CExpr
67+joinL :: [LExpr] -> [String] -> IParser LExpr
7268joinL [e] [] = return e
73−joinL (a:b:es) (op:ops) = joinL (epos a b (Binop op a b) : es) ops
69+joinL (a:b:es) (op:ops) = joinL (merge a b (Binop op a b) : es) ops
7470joinL _ _ = fail "Ill-formed binary expression. Report a compiler bug."
7571
76−joinR :: [CExpr] -> [String] -> IParser CExpr
72+joinR :: [LExpr] -> [String] -> IParser LExpr
7773joinR [e] [] = return e
7874joinR (a:b:es) (op:ops) = do e <- joinR (b:es) ops
79− return (epos a e (Binop op a e))
75+ return (merge a e (Binop op a e))
8076joinR _ _ = fail "Ill-formed binary expression. Report a compiler bug."
8177
82−getAssoc :: OpTable -> Int -> [(String,CExpr)] -> IParser Assoc
78+getAssoc :: OpTable -> Int -> [(String,LExpr)] -> IParser Assoc
8379getAssoc table n eops
8480 | all (==L) assocs = return L
8581 | all (==R) assocs = return R
compiler/Parse/Expr.hs+9−8
@@ -1,7 +1,5 @@
11module Parse.Expr (def,term) where
22
3−import Ast
4−import Located
53import Control.Applicative ((<$>), (<*>))
64import Control.Monad
75import Data.Char (isSymbol, isDigit)
@@ -15,6 +13,9 @@ import Parse.Patterns
1513import Parse.Binops
1614import Parse.Types
1715
16+import Ast
17+import Located
18+
1819import Guid
1920import Types.Types (Type (VarT), Scheme (Forall))
2021
@@ -70,7 +71,7 @@ listTerm =
7071 return e
7172 ])
7273
73−parensTerm :: IParser CExpr
74+parensTerm :: IParser LExpr
7475parensTerm = parens $ choice
7576 [ do start <- getPosition
7677 op <- try anyOp
@@ -93,7 +94,7 @@ parensTerm = parens $ choice
9394 _ -> pos start end (tuple es)
9495 ]
9596
96−recordTerm :: IParser CExpr
97+recordTerm :: IParser LExpr
9798recordTerm = brackets $ choice [ misc, addLocation record ]
9899 where field = do
99100 fDefs <- (:) <$> (PVar <$> rLabel) <*> spacePrefix patternTerm
@@ -125,14 +126,14 @@ recordTerm = brackets $ choice [ misc, addLocation record ]
125126 Nothing -> try (insert record) <|> try (modify record)
126127
127128
128−term :: IParser CExpr
129+term :: IParser LExpr
129130term = addLocation (choice [ numTerm, strTerm, chrTerm, listTerm, accessor ])
130131 <|> accessible (addLocation varTerm <|> parensTerm <|> recordTerm)
131132 <?> "basic term (4, x, 'c', etc.)"
132133
133134-------- Applications --------
134135
135−appExpr :: IParser CExpr
136+appExpr :: IParser LExpr
136137appExpr = do
137138 tlist <- spaceSep1 term
138139 return $ case tlist of
@@ -141,7 +142,7 @@ appExpr = do
141142
142143-------- Normal Expressions --------
143144
144−binaryExpr :: IParser CExpr
145+binaryExpr :: IParser LExpr
145146binaryExpr = binops [] appExpr anyOp
146147
147148ifExpr :: IParser Expr
@@ -159,7 +160,7 @@ ifExpr = reserved "if" >> whitespace >> (normal <|> multiIf)
159160 b <- expr ; whitespace ; string "->" ; whitespace
160161 (,) b <$> expr
161162
162−lambdaExpr :: IParser CExpr
163+lambdaExpr :: IParser LExpr
163164lambdaExpr = do char '\\' <|> char '\x03BB' <?> "anonymous function"
164165 whitespace
165166 pats <- spaceSep1 patternTerm
compiler/Parse/Library.hs → compiler/Parse/Helpers.hsrenamed+9−9
@@ -1,13 +1,13 @@
1+module Parse.Helpers where
12
2−module Parse.Library where
3−
4−import Ast
5−import Located
63import Control.Applicative ((<$>),(<*>))
74import Control.Monad
85import Control.Monad.State
96import Data.Char (isUpper)
10−import Rename (deprime)
7+import SourceSyntax.Helpers (isOp)
8+import SourceSyntax.Location as Location
9+import SourceSyntax.Expression
10+import SourceSyntax.Rename (deprime)
1111import Text.Parsec hiding (newline,spaces,State)
1212import Text.Parsec.Indent
1313
@@ -124,14 +124,14 @@ parens = surround '(' ')' "paren"
124124brackets :: IParser a -> IParser a
125125brackets = surround '{' '}' "bracket"
126126
127−addLocation :: IParser Expr -> IParser CExpr
127+addLocation :: IParser Expr -> IParser LExpr
128128addLocation expr = do
129129 start <- getPosition
130130 e <- expr
131131 end <- getPosition
132− return (pos start end e)
132+ return (Location.at start end e)
133133
134−accessible :: IParser CExpr -> IParser CExpr
134+accessible :: IParser LExpr -> IParser LExpr
135135accessible expr = do
136136 start <- getPosition
137137 ce@(L s t e) <- expr
@@ -143,7 +143,7 @@ accessible expr = do
143143 Just _ -> accessible $ do
144144 v <- var <?> "field access (e.g. List.map)"
145145 end <- getPosition
146− return (pos start end (f v))
146+ return (Location.at start end (f v))
147147 case e of Var (c:cs) | isUpper c -> rest (\v -> Var (c:cs ++ '.':v))
148148 | otherwise -> rest (Access ce)
149149 _ -> rest (Access ce)
compiler/Parse/Patterns.hs+1−1
@@ -1,5 +1,5 @@
11
2−module Parse.Patterns (patternTerm, patternExpr, makeLambda, flattenPatterns) where
2+module Parse.Pattern (patternTerm, patternExpr, makeLambda, flattenPatterns) where
33
44import Ast
55import Located
compiler/Parse/Types.hs+8−7
@@ -1,6 +1,5 @@
11module Parse.Types where
22
3−import Ast
43import Control.Applicative ((<$>),(<*>))
54import Control.Monad (liftM,mapM)
65import Data.Char (isUpper,isLower)
@@ -9,8 +8,10 @@ import Data.List (lookup,intercalate)
98import Text.Parsec
109import Text.Parsec.Indent
1110
12−import Located
13−import Parse.Library
11+import SourceSyntax.Location as Located
12+import SourceSyntax.Expression
13+import SourceSyntax.Declaration
14+import Parse.Helpers
1415import Types.Types hiding (parens,string)
1516import Guid
1617
@@ -69,7 +70,7 @@ typeConstructor :: IParser (String, [ParseType])
6970typeConstructor = (,) <$> (capVar <?> "another type constructor")
7071 <*> spacePrefix (typeSimple <|> typeUnambiguous)
7172
72−typeAlias :: IParser [Statement]
73+typeAlias :: IParser [Declaration]
7374typeAlias = do
7475 start <- getPosition
7576 reserved "type" <?> "type alias (type Point = {x:Int, y:Int})"
@@ -91,13 +92,13 @@ typeAlias = do
9192toConstructor start end alias Nothing kvs =
9293 Definition (FnDef alias args (loc (Record rec)))
9394 where
94− loc = pos start end
95+ loc = Located.at start end
9596 args = map fst kvs
9697 rec = map (\a -> (a, [], loc (Var a))) args
9798toConstructor start end alias (Just _) kvs =
9899 Definition (FnDef alias (args++["_ext_"]) (loc rec))
99100 where
100− loc = pos start end
101+ loc = Located.at start end
101102 args = map fst kvs
102103 rec = foldl insert (Var "_ext_") (zip args (map (loc . Var) args))
103104 insert e (k,v) = Insert (loc e) k v
@@ -107,7 +108,7 @@ typeAnnotation = TypeAnnotation <$> try start <*> (toType <$> typeExpr)
107108 where start = do v <- lowVar <|> parens symOp
108109 whitespace ; hasType ; whitespace ; return v
109110
110−datatype :: IParser Statement
111+datatype :: IParser Declaration
111112datatype = do
112113 reserved "data" <?> "datatype definition (data T = A | B | ...)"
113114 forcedWS ; name <- capVar <?> "name of data-type" ; args <- spacePrefix lowVar
compiler/SourceSyntax/Declaration.hs+4−1
@@ -11,5 +11,8 @@ data Declaration
1111 | TypeAlias String [X] Type
1212 | ImportEvent String Expr.LExpr String Type
1313 | ExportEvent String String Type
14− | Fixity Int String
14+ | Fixity Assoc Int String
1515 deriving (Eq, Show, Data, Typeable)
16+
17+data Assoc = L | N | R
18+ deriving (Eq, Show, Data, Typeable)
compiler/Transform/Rename.hs → compiler/SourceSyntax/Rename.hsrenamed+12−7
@@ -1,13 +1,16 @@
11{-# LANGUAGE GeneralizedNewtypeDeriving #-}
2−module Rename (renameModule, derename, deprime) where
2+module SourceSyntax.Rename (renameModule, derename, deprime) where
33
4−import Ast
5−import Located
64import Control.Arrow (first)
75import Control.Monad (ap, liftM, foldM, mapM, Monad, zipWithM)
86import Control.Monad.State (evalState, State, get, put)
97import Data.Char (isLower,isDigit)
108import Guid
9+import SourceSyntax.Location
10+import SourceSyntax.Pattern
11+import SourceSyntax.Expression
12+import SourceSyntax.Declaration hiding (Assoc(..))
13+import SourceSyntax.Module
1114
1215derename var
1316 | isDigit (last var) = reverse . tail . dropWhile isDigit $ reverse var
@@ -33,7 +36,7 @@ instance Rename Def where
3336 rename env (TypeAnnotation n t) = return (TypeAnnotation (env n) t)
3437
3538
36−instance Rename Statement where
39+instance Rename Declaration where
3740 rename env stmt =
3841 case stmt of
3942 Definition def -> Definition `liftM` rename env def
@@ -126,10 +129,10 @@ patternExtend pattern env =
126129 case pattern of
127130 PAnything -> return (PAnything, env)
128131 PVar x -> first PVar `liftM` extend env x
129− PAsVar x p -> do
132+ PAlias x p -> do
130133 (x', env') <- extend env x
131134 (p', env'') <- patternExtend p env'
132− return (PAsVar x' p', env'')
135+ return (PAlias x' p', env'')
133136 PData name ps ->
134137 first (PData name . reverse) `liftM` foldM f ([], env) ps
135138 where f (rps,env') p = do (rp,env'') <- patternExtend p env'
@@ -137,7 +140,9 @@ patternExtend pattern env =
137140 PRecord fs ->
138141 return (pattern, foldr (\f e n -> if n == f then f else env n) env fs)
139142
140−patternRename :: (String -> String) -> (Pattern, CExpr) -> GuidCounter (Pattern, CExpr)
143+patternRename :: (String -> String)
144+ -> (Pattern, LExpr)
145+ -> GuidCounter (Pattern, LExpr)
141146patternRename env (p,e) = do
142147 (rp,env') <- patternExtend p env
143148 re <- rename env' e
compiler/Types/Solver.hs+13−8
@@ -14,6 +14,8 @@ import Types.Types
1414import Types.Substitutions
1515import Types.Alias (dealias)
1616
17+import System.IO.Unsafe
18+
1719isSolved ss (L _ _ (t1 :=: t2)) = t1 == t2
1820isSolved ss (L _ _ (x :<<: _)) = isJust (lookup x ss)
1921isSolved ss c = False
@@ -21,12 +23,15 @@ isSolved ss c = False
2123type Aliases = Map.Map String ([X],Type)
2224
2325crush :: Aliases -> Scheme -> GuidCounter (Either String Scheme)
24−crush aliases (Forall xs cs t) =
26+crush aliases forall@(Forall xs cs t) =
2527 do subs <- solver aliases Map.empty cs
2628 return $ do ss' <- subs
2729 let ss = Map.toList ss'
2830 cs' = filter (not . isSolved ss) (subst ss cs)
29− return $ Forall xs cs' (subst ss t)
31+ f x = (unsafePerformIO $ do
32+ print forall >> putStrLn "-------"
33+ print x >> putStrLn "~~~~~~~") `seq` x
34+ return . f $ Forall xs cs' (subst ss t)
3035
3136schemeSubHelp txt span x s t1 rltn t2 = do
3237 (t1',cs1) <- sub t1
@@ -36,11 +41,10 @@ schemeSubHelp txt span x s t1 rltn t2 = do
3641 | otherwise = do (st, cs) <- concretize s
3742 return (subst [(x,st)] t, cs)
3843
39−schemeSub aliases x s c =
40− do s' <- crush aliases s
41− case s' of
42− Right s'' -> Right `liftM` schemeSub' x s'' c
43− Left err -> return $ Left err
44+schemeSub x s' c =
45+ case s' of
46+ Right s'' -> Right `liftM` schemeSub' x s'' c
47+ Left err -> return $ Left err
4448
4549schemeSub' x s c@(L txt span constraint) =
4650 case constraint of
@@ -170,7 +174,8 @@ solver aliases subs (L txt span c : cs) =
170174
171175 x :<<: s
172176 | any (occurs x) cs ->
173− do css <- mapM (schemeSub aliases x s) cs
177+ do s' <- crush aliases s
178+ css <- mapM (schemeSub x s') cs
174179 case lefts css of
175180 err : _ -> return $ Left err
176181 [] -> solv (concat (rights css))
compiler/Types/Types.hs+1−1
@@ -1,7 +1,7 @@
11{-# LANGUAGE DeriveDataTypeable #-}
22module Types.Types where
33
4−import Located
4+import SourceSyntax.Location
55import Data.Char (isDigit)
66import Data.List (intercalate,isPrefixOf)
77import qualified Data.Set as Set
compiler/Types/Unify.hs+4−2
@@ -19,7 +19,9 @@ unify hints modul@(Module _ _ _ stmts) = run $ do
1919 case result of
2020 Left err -> return (Left err)
2121 Right (schemes, constraints) ->
22− do subs <- Solver.solver (Alias.get stmts) Map.empty constraints
22+ do subs <- unsafePerformIO (mapM print constraints) `seq`
23+ Solver.solver (Alias.get stmts) Map.empty constraints
2324 let ss = either (const []) Map.toList subs
24− unsafePerformIO (mapM print . map (second (Subst.subst ss)) $ concatMap Map.toList schemes) `seq` return subs
25+ -- unsafePerformIO (mapM print . map (second (Subst.subst ss)) $ concatMap Map.toList schemes) `seq`
26+ return subs
2527