Skip to content

Commit ea3e968

Browse files
committed
Still more work on mutually recursive functions, still need to fix examples
1 parent 24872f8 commit ea3e968

File tree

21 files changed

+295
-318
lines changed

21 files changed

+295
-318
lines changed

examples/passing/Import.purs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
module Hello where
1+
module M1 where
2+
23
id :: forall a. a -> a
34
id = \x -> x
45

5-
module Nested where
6-
import Hello (id)
6+
foo = id
77

8-
foo = id
8+
module M2 where
99

10-
import Hello.Nested
10+
import M1
1111

12-
main = \() -> foo 42
12+
main = \() -> foo 42

examples/passing/Module.purs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
module Test where
1+
module M1 where
22

33
data Foo = Foo String
44

5-
foo :: Test.Foo -> String
5+
foo :: M1.Foo -> String
66
foo = \f -> case f of Foo s -> s ++ "foo"
77

88
bar :: Foo -> String
@@ -11,15 +11,10 @@ module Test where
1111
incr :: Number -> Number
1212
incr x = x + 1
1313

14-
module Inner where
14+
module M2 where
1515

16-
inner = "Inner"
16+
baz :: M1.Foo -> String
17+
baz = M1.foo
1718

18-
baz :: Test.Foo -> String
19-
baz = Test.foo
20-
21-
innerCopy :: String
22-
innerCopy = Test.Inner.inner
23-
24-
match :: Test.Foo -> String
25-
match = \f -> case f of Test.Foo s -> s ++ "foo"
19+
match :: M1.Foo -> String
20+
match = \f -> case f of M1.Foo s -> s ++ "foo"

examples/passing/MutRec.purs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
f 0 = 0
2-
f x = g x + 1
1+
module MutRec where
32

4-
g x = f (x / 2)
3+
f 0 = 0
4+
f x = g x + 1
5+
6+
g x = f (x / 2)

src/Language/PureScript.hs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,13 @@ import Language.PureScript.TypeDeclarations as P
3030
import Language.PureScript.BindingGroups as P
3131

3232
import Data.List (intercalate)
33-
import Data.Maybe (mapMaybe)
34-
import Control.Monad ((>=>))
33+
import Control.Monad (forM_, (>=>))
3534

36-
compile :: [Declaration] -> Either String (String, String, Environment)
37-
compile decls = do
38-
bracketted <- rebracket decls
39-
desugared <- desugarCases >=> desugarTypeDeclarations >=> (return . createBindingGroups) $ bracketted
40-
(_, env) <- runCheck (typeCheckAll desugared)
41-
let js = prettyPrintJS . map optimize . concat . mapMaybe (\decl -> declToJs Nothing global decl env) $ desugared
42-
let exts = intercalate "\n" . mapMaybe (externToPs 0 global env) $ desugared
35+
compile :: [Module] -> Either String (String, String, Environment)
36+
compile ms = do
37+
bracketted <- rebracket ms
38+
desugared <- desugarCasesModule >=> desugarTypeDeclarationsModule >=> (return . createBindingGroupsModule) $ bracketted
39+
(_, env) <- runCheck $ forM_ desugared $ \(Module moduleName decls) -> typeCheckAll (ModuleName moduleName) decls
40+
let js = prettyPrintJS . map optimize . concatMap (flip moduleToJs env) $ desugared
41+
let exts = intercalate "\n" . map (flip moduleToPs env) $ desugared
4342
return (js, exts, env)

src/Language/PureScript/BindingGroups.hs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
-----------------------------------------------------------------------------
1414

1515
module Language.PureScript.BindingGroups (
16-
createBindingGroups
16+
createBindingGroups,
17+
createBindingGroupsModule
1718
) where
1819

1920
import Data.Graph
@@ -24,6 +25,9 @@ import Language.PureScript.Names
2425
import Language.PureScript.Values
2526
import Language.PureScript.Scope (usedNames)
2627

28+
createBindingGroupsModule :: [Module] -> [Module]
29+
createBindingGroupsModule = map $ \(Module name ds) -> Module name (createBindingGroups ds)
30+
2731
createBindingGroups :: [Declaration] -> [Declaration]
2832
createBindingGroups ds =
2933
let
@@ -33,7 +37,7 @@ createBindingGroups ds =
3337
verts = map (\d -> (d, getIdent d, usedNames d `intersect` allIdents)) values
3438
sorted = map toBindingGroup $ stronglyConnComp verts
3539
in
36-
map handleModuleDeclaration nonValues ++ sorted
40+
nonValues ++ sorted
3741

3842
isValueDecl :: Declaration -> Bool
3943
isValueDecl (ValueDeclaration _ _ _ _) = True
@@ -52,7 +56,3 @@ fromValueDecl :: Declaration -> (Ident, Value)
5256
fromValueDecl (ValueDeclaration ident [] Nothing val) = (ident, val)
5357
fromValueDecl (ValueDeclaration _ _ _ _) = error "Binders should have been desugared"
5458
fromValueDecl _ = error "Expected ValueDeclaration"
55-
56-
handleModuleDeclaration :: Declaration -> Declaration
57-
handleModuleDeclaration (ModuleDeclaration name ds') = ModuleDeclaration name $ createBindingGroups ds'
58-
handleModuleDeclaration other = other

src/Language/PureScript/CaseDeclarations.hs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,23 @@
1313
-----------------------------------------------------------------------------
1414

1515
module Language.PureScript.CaseDeclarations (
16-
desugarCases
16+
desugarCases,
17+
desugarCasesModule
1718
) where
1819

1920
import Data.List (groupBy)
20-
import Control.Monad (join, unless)
21+
import Control.Applicative ((<$>))
22+
import Control.Monad (forM, join, unless)
2123
import Control.Monad.Error.Class
2224

2325
import Language.PureScript.Names
2426
import Language.PureScript.Values
2527
import Language.PureScript.Declarations
2628
import Language.PureScript.Scope
2729

30+
desugarCasesModule :: [Module] -> Either String [Module]
31+
desugarCasesModule ms = forM ms $ \(Module name ds) -> Module name <$> desugarCases ds
32+
2833
desugarCases :: [Declaration] -> Either String [Declaration]
2934
desugarCases = fmap join . mapM toDecls . groupBy inSameGroup
3035

@@ -39,9 +44,6 @@ toDecls ds@(ValueDeclaration ident bs _ _ : _) = do
3944
unless (all ((== map length bs) . map length . fst) tuples) $
4045
throwError $ "Argument list lengths differ in declaration " ++ show ident
4146
return [makeCaseDeclaration ident tuples]
42-
toDecls [ModuleDeclaration name decls] = do
43-
desugared <- desugarCases decls
44-
return [ModuleDeclaration name desugared]
4547
toDecls ds = return ds
4648

4749
toTuple :: Declaration -> ([[Binder]], (Maybe Guard, Value))
@@ -53,7 +55,7 @@ makeCaseDeclaration ident alternatives =
5355
let
5456
argPattern = map length . fst . head $ alternatives
5557
args = take (sum argPattern) $ unusedNames (ident, alternatives)
56-
vars = map (\arg -> Var (Qualified global arg)) args
58+
vars = map (\arg -> Var (Qualified Nothing arg)) args
5759
binders = [ (join bs, g, val) | (bs, (g, val)) <- alternatives ]
5860
value = foldr (\args' ret -> Abs args' ret) (Case vars binders) (rearrange argPattern args)
5961
in

src/Language/PureScript/CodeGen/Externs.hs

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,29 +13,37 @@
1313
-----------------------------------------------------------------------------
1414

1515
module Language.PureScript.CodeGen.Externs (
16-
externToPs
16+
moduleToPs
1717
) where
1818

19-
import Data.Maybe (mapMaybe)
19+
import Data.Maybe (maybeToList, mapMaybe)
2020
import qualified Data.Map as M
2121
import Language.PureScript.Declarations
2222
import Language.PureScript.TypeChecker.Monad
2323
import Language.PureScript.Pretty
2424
import Language.PureScript.Names
25+
import Data.List (intercalate)
2526

26-
externToPs :: Int -> ModulePath -> Environment -> Declaration -> Maybe String
27-
externToPs indent path env (ValueDeclaration name _ _ _) = do
27+
moduleToPs :: Module -> Environment -> String
28+
moduleToPs (Module pname@(ProperName moduleName) decls) env =
29+
"module " ++ moduleName ++ " where\n" ++
30+
(intercalate "\n" . map (" " ++) . concatMap (declToPs (ModuleName pname) env) $ decls)
31+
32+
declToPs :: ModuleName -> Environment -> Declaration -> [String]
33+
declToPs path env (ValueDeclaration name _ _ _) = maybeToList $ do
2834
(ty, _) <- M.lookup (path, name) $ names env
29-
return $ replicate indent ' ' ++ "foreign import " ++ show name ++ " :: " ++ prettyPrintType ty
30-
externToPs indent path env (DataDeclaration name _ _) = do
35+
return $ "foreign import " ++ show name ++ " :: " ++ prettyPrintType ty
36+
declToPs path env (BindingGroupDeclaration vals) = do
37+
flip mapMaybe vals $ \(name, _) -> do
38+
(ty, _) <- M.lookup (path, name) $ names env
39+
return $ "foreign import " ++ show name ++ " :: " ++ prettyPrintType ty
40+
declToPs path env (DataDeclaration name _ _) = maybeToList $ do
3141
(kind, _) <- M.lookup (path, name) $ types env
32-
return $ replicate indent ' ' ++ "foreign import data " ++ show name ++ " :: " ++ prettyPrintKind kind
33-
externToPs indent _ _ (ExternMemberDeclaration member name ty) =
34-
return $ replicate indent ' ' ++ "foreign import member " ++ show member ++ " " ++ show name ++ " :: " ++ prettyPrintType ty
35-
externToPs indent _ _ (ExternDataDeclaration name kind) =
36-
return $ replicate indent ' ' ++ "foreign import data " ++ show name ++ " :: " ++ prettyPrintKind kind
37-
externToPs indent _ _ (TypeSynonymDeclaration name args ty) =
38-
return $ replicate indent ' ' ++ "type " ++ show name ++ " " ++ unwords args ++ " = " ++ prettyPrintType ty
39-
externToPs indent path env (ModuleDeclaration name decls) =
40-
return $ replicate indent ' ' ++ "module " ++ show name ++ " where\n" ++ unlines (mapMaybe (externToPs (indent + 2) (subModule path name) env) decls)
41-
externToPs _ _ _ _ = Nothing
42+
return $ "foreign import data " ++ show name ++ " :: " ++ prettyPrintKind kind
43+
declToPs _ _ (ExternMemberDeclaration member name ty) =
44+
return $ "foreign import member " ++ show member ++ " " ++ show name ++ " :: " ++ prettyPrintType ty
45+
declToPs _ _ (ExternDataDeclaration name kind) =
46+
return $ "foreign import data " ++ show name ++ " :: " ++ prettyPrintKind kind
47+
declToPs _ _ (TypeSynonymDeclaration name args ty) =
48+
return $ "type " ++ show name ++ " " ++ unwords args ++ " = " ++ prettyPrintType ty
49+
declToPs _ _ _ = []

src/Language/PureScript/CodeGen/JS.hs

Lines changed: 42 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414

1515
module Language.PureScript.CodeGen.JS (
1616
module AST,
17-
declToJs
17+
declToJs,
18+
moduleToJs
1819
) where
1920

2021
import Data.Maybe (mapMaybe)
@@ -31,52 +32,48 @@ import Language.PureScript.Pretty.Common
3132
import Language.PureScript.CodeGen.Monad
3233
import Language.PureScript.CodeGen.JS.AST as AST
3334
import Language.PureScript.TypeChecker.Monad (NameKind(..))
34-
import Debug.Trace (trace)
3535

36-
declToJs :: Maybe Ident -> ModulePath -> Declaration -> Environment -> Maybe [JS]
37-
declToJs curMod mp (ValueDeclaration ident _ _ (Abs args ret)) e =
38-
Just $ JSFunction (Just ident) args (JSBlock [JSReturn (valueToJs mp e ret)]) :
39-
maybe [] (return . setProperty (identToJs ident) (JSVar ident)) curMod
40-
declToJs curMod mp (ValueDeclaration ident _ _ val) e =
41-
Just $ JSVariableIntroduction ident (Just (valueToJs mp e val)) :
42-
maybe [] (return . setProperty (identToJs ident) (JSVar ident)) curMod
43-
declToJs curMod mp (BindingGroupDeclaration vals) e = trace (show [ JSApp (JSFunction Nothing [] (JSBlock (concatMap (\(ident, val) ->
44-
JSVariableIntroduction ident (Just (valueToJs mp e val)) :
45-
maybe [] (return . setProperty (identToJs ident) (JSVar ident)) curMod
46-
) vals))) []
47-
]) $
48-
Just [ JSApp (JSFunction Nothing [] (JSBlock (concatMap (\(ident, val) ->
49-
JSVariableIntroduction ident (Just (valueToJs mp e val)) :
50-
maybe [] (return . setProperty (identToJs ident) (JSVar ident)) curMod
51-
) vals))) []
52-
]
53-
declToJs curMod _ (ExternMemberDeclaration member ident _) _ =
54-
Just $ JSFunction (Just ident) [Ident "value"] (JSBlock [JSReturn (JSAccessor member (JSVar (Ident "value")))]) :
55-
maybe [] (return . setProperty (show ident) (JSVar ident)) curMod
56-
declToJs curMod mp (DataDeclaration _ _ ctors) _ =
36+
moduleToJs :: Module -> Environment -> [JS]
37+
moduleToJs (Module pname@(ProperName name) decls) env =
38+
[ JSVariableIntroduction (Ident name) Nothing
39+
, JSApp (JSFunction Nothing [Ident name]
40+
(JSBlock (concat $ mapMaybe (\decl -> declToJs (ModuleName pname) decl env) decls)))
41+
[JSAssignment (JSAssignVariable (Ident name))
42+
(JSBinary Or (JSVar (Ident name)) (JSObjectLiteral []))]
43+
]
44+
45+
declToJs :: ModuleName -> Declaration -> Environment -> Maybe [JS]
46+
declToJs mp (ValueDeclaration ident _ _ (Abs args ret)) e =
47+
Just [ JSFunction (Just ident) args (JSBlock [JSReturn (valueToJs mp e ret)]),
48+
setProperty (identToJs ident) (JSVar ident) mp ]
49+
declToJs mp (ValueDeclaration ident _ _ val) e =
50+
Just [ JSVariableIntroduction ident (Just (valueToJs mp e val)),
51+
setProperty (identToJs ident) (JSVar ident) mp ]
52+
declToJs mp (BindingGroupDeclaration vals) e =
53+
Just $ concatMap (\(ident, val) ->
54+
[ JSVariableIntroduction ident (Just (valueToJs mp e val)),
55+
setProperty (identToJs ident) (JSVar ident) mp ]
56+
) vals
57+
declToJs mp (ExternMemberDeclaration member ident _) _ =
58+
Just [ JSFunction (Just ident) [Ident "value"] (JSBlock [JSReturn (JSAccessor member (JSVar (Ident "value")))]),
59+
setProperty (show ident) (JSVar ident) mp ]
60+
declToJs mp (DataDeclaration _ _ ctors) _ =
5761
Just $ flip concatMap ctors $ \(pn@(ProperName ctor), maybeTy) ->
5862
let
5963
ctorJs =
6064
case maybeTy of
61-
Nothing -> JSVariableIntroduction (Ident ctor) (Just (JSObjectLiteral [ ("ctor", JSStringLiteral (show (Qualified mp pn))) ]))
65+
Nothing -> JSVariableIntroduction (Ident ctor) (Just (JSObjectLiteral [ ("ctor", JSStringLiteral (show (Qualified (Just mp) pn))) ]))
6266
Just _ -> JSFunction (Just (Ident ctor)) [Ident "value"]
6367
(JSBlock [JSReturn
64-
(JSObjectLiteral [ ("ctor", JSStringLiteral (show (Qualified mp pn)))
68+
(JSObjectLiteral [ ("ctor", JSStringLiteral (show (Qualified (Just mp) pn)))
6569
, ("value", JSVar (Ident "value")) ])])
66-
in ctorJs : maybe [] (return . setProperty ctor (JSVar (Ident ctor))) curMod
67-
declToJs curMod mp (ModuleDeclaration pn@(ProperName name) decls) env =
68-
Just $ [ JSVariableIntroduction (Ident name) Nothing
69-
, JSApp (JSFunction Nothing [Ident name]
70-
(JSBlock (concat $ mapMaybe (\decl -> declToJs (Just (Ident name)) (subModule mp pn) decl env) decls)))
71-
[JSAssignment (JSAssignVariable (Ident name))
72-
(JSBinary Or (JSVar (Ident name)) (JSObjectLiteral []))]] ++
73-
maybe [] (return . setProperty name (JSVar (Ident name))) curMod
74-
declToJs _ _ _ _ = Nothing
70+
in [ ctorJs, setProperty ctor (JSVar (Ident ctor)) mp ]
71+
declToJs _ _ _ = Nothing
7572

76-
setProperty :: String -> JS -> Ident -> JS
77-
setProperty prop val curMod = JSAssignment (JSAssignProperty prop (JSAssignVariable curMod)) val
73+
setProperty :: String -> JS -> ModuleName -> JS
74+
setProperty prop val (ModuleName (ProperName moduleName)) = JSAssignment (JSAssignProperty prop (JSAssignVariable (Ident moduleName))) val
7875

79-
valueToJs :: ModulePath -> Environment -> Value -> JS
76+
valueToJs :: ModuleName -> Environment -> Value -> JS
8077
valueToJs _ _ (NumericLiteral n) = JSNumericLiteral n
8178
valueToJs _ _ (StringLiteral s) = JSStringLiteral s
8279
valueToJs _ _ (BooleanLiteral b) = JSBooleanLiteral b
@@ -94,19 +91,16 @@ valueToJs m e (Abs args val) = JSFunction Nothing args (JSBlock [JSReturn (value
9491
valueToJs m e (Unary op val) = JSUnary op (valueToJs m e val)
9592
valueToJs m e (Binary op v1 v2) = JSBinary op (valueToJs m e v1) (valueToJs m e v2)
9693
valueToJs m e (Var ident) = case M.lookup (qualify m ident) (names e) of
97-
Just (_, Alias aliasModule aliasIdent) -> qualifiedToJS identToJs (Qualified aliasModule aliasIdent)
94+
Just (_, Alias aliasModule aliasIdent) -> qualifiedToJS identToJs (Qualified (Just aliasModule) aliasIdent)
9895
_ -> qualifiedToJS identToJs ident
9996
valueToJs m e (TypedValue val _) = valueToJs m e val
10097
valueToJs _ _ _ = error "Invalid argument to valueToJs"
10198

10299
qualifiedToJS :: (a -> String) -> Qualified a -> JS
103-
qualifiedToJS f (Qualified (ModulePath parts) a) =
104-
delimited (f a : reverse (map show parts))
105-
where delimited [part] = JSVar (Ident (part))
106-
delimited (part:parts') = JSAccessor part (delimited parts')
107-
delimited _ = error "Invalid argument to delimited"
100+
qualifiedToJS f (Qualified (Just (ModuleName (ProperName m))) a) = JSAccessor (f a) (JSVar (Ident m))
101+
qualifiedToJS f (Qualified Nothing a) = JSVar (Ident (f a))
108102

109-
bindersToJs :: ModulePath -> Environment -> [([Binder], Maybe Guard, Value)] -> [JS] -> Gen JS
103+
bindersToJs :: ModuleName -> Environment -> [([Binder], Maybe Guard, Value)] -> [JS] -> Gen JS
110104
bindersToJs m e binders vals = do
111105
setNextName $ firstUnusedName (binders, vals)
112106
valNames <- replicateM (length vals) fresh
@@ -122,7 +116,7 @@ bindersToJs m e binders vals = do
122116
binderToJs m e v done'' b
123117
go _ _ _ _ = error "Invalid arguments to bindersToJs"
124118

125-
binderToJs :: ModulePath -> Environment -> String -> [JS] -> Binder -> Gen [JS]
119+
binderToJs :: ModuleName -> Environment -> String -> [JS] -> Binder -> Gen [JS]
126120
binderToJs _ _ _ done NullBinder = return done
127121
binderToJs _ _ varName done (StringBinder str) =
128122
return [JSIfElse (JSBinary EqualTo (JSVar (Ident varName)) (JSStringLiteral str)) (JSBlock done) Nothing]
@@ -135,11 +129,11 @@ binderToJs _ _ varName done (BooleanBinder False) =
135129
binderToJs _ _ varName done (VarBinder ident) =
136130
return (JSVariableIntroduction ident (Just (JSVar (Ident varName))) : done)
137131
binderToJs m _ varName done (NullaryBinder ctor) =
138-
return [JSIfElse (JSBinary EqualTo (JSAccessor "ctor" (JSVar (Ident varName))) (JSStringLiteral (show (uncurry Qualified $ qualify m ctor)))) (JSBlock done) Nothing]
132+
return [JSIfElse (JSBinary EqualTo (JSAccessor "ctor" (JSVar (Ident varName))) (JSStringLiteral (show ((\(mp, nm) -> Qualified (Just mp) nm) $ qualify m ctor)))) (JSBlock done) Nothing]
139133
binderToJs m e varName done (UnaryBinder ctor b) = do
140134
value <- fresh
141135
js <- binderToJs m e value done b
142-
return [JSIfElse (JSBinary EqualTo (JSAccessor "ctor" (JSVar (Ident varName))) (JSStringLiteral (show (uncurry Qualified $ qualify m ctor)))) (JSBlock (JSVariableIntroduction (Ident value) (Just (JSAccessor "value" (JSVar (Ident varName)))) : js)) Nothing]
136+
return [JSIfElse (JSBinary EqualTo (JSAccessor "ctor" (JSVar (Ident varName))) (JSStringLiteral (show ((\(mp, nm) -> Qualified (Just mp) nm) $ qualify m ctor)))) (JSBlock (JSVariableIntroduction (Ident value) (Just (JSAccessor "value" (JSVar (Ident varName)))) : js)) Nothing]
143137
binderToJs m e varName done (ObjectBinder bs) = go done bs
144138
where
145139
go :: [JS] -> [(String, Binder)] -> Gen [JS]
@@ -174,7 +168,7 @@ binderToJs m e varName done (NamedBinder ident binder) = do
174168
js <- binderToJs m e varName done binder
175169
return (JSVariableIntroduction ident (Just (JSVar (Ident varName))) : js)
176170

177-
statementToJs :: ModulePath -> Environment -> Statement -> JS
171+
statementToJs :: ModuleName -> Environment -> Statement -> JS
178172
statementToJs m e (VariableIntroduction ident value) = JSVariableIntroduction ident (Just (valueToJs m e value))
179173
statementToJs m e (Assignment target value) = JSAssignment (JSAssignVariable target) (valueToJs m e value)
180174
statementToJs m e (While cond sts) = JSWhile (valueToJs m e cond) (JSBlock (map (statementToJs m e) sts))

src/Language/PureScript/Declarations.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ data Associativity = Infixl | Infixr deriving (Show, D.Data, D.Typeable)
2929

3030
data Fixity = Fixity Associativity Precedence deriving (Show, D.Data, D.Typeable)
3131

32+
data Module = Module ProperName [Declaration]
33+
3234
data Declaration
3335
= DataDeclaration ProperName [String] [(ProperName, Maybe PolyType)]
3436
| TypeSynonymDeclaration ProperName [String] PolyType
@@ -39,6 +41,5 @@ data Declaration
3941
| ExternMemberDeclaration String Ident PolyType
4042
| ExternDataDeclaration ProperName Kind
4143
| FixityDeclaration Fixity String
42-
| ModuleDeclaration ProperName [Declaration]
43-
| ImportDeclaration ModulePath (Maybe [Ident])
44+
| ImportDeclaration ModuleName (Maybe [Ident])
4445
deriving (Show, D.Data, D.Typeable)

0 commit comments

Comments
 (0)