mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-23 11:42:49 -06:00
Translating linearization functions to Haskell: more simplifications
+ Some additional simplifying rewrites. + Use an intermediate representation for Haskell types, for separation of concerns and cleaner code. + Pretty printer layout tuning + Code cleanup.
This commit is contained in:
@@ -56,7 +56,10 @@ concrete2haskell opts gr cenv absname cnc modinfo =
|
|||||||
|
|
||||||
-- signature c = "lin"<>c<+>"::"<+>"A."<>gId c<+>"->"<+>"Lin"<>c
|
-- signature c = "lin"<>c<+>"::"<+>"A."<>gId c<+>"->"<+>"Lin"<>c
|
||||||
-- signature c = "--lin"<>c<+>":: (Applicative f,Monad f) =>"<+>"A."<>gId c<+>"->"<+>"f Lin"<>c
|
-- signature c = "--lin"<>c<+>":: (Applicative f,Monad f) =>"<+>"A."<>gId c<+>"->"<+>"f Lin"<>c
|
||||||
signature c = "lin"<>c<+>"::"<+>"A."<>gId c<+>"->"<+>pure ("Lin"<>c)
|
signature c = "lin"<>c<+>"::"<+>Fun abs (pure lin)
|
||||||
|
where
|
||||||
|
abs = tcon0 (prefixIdent "A." (gId c))
|
||||||
|
lin = tcon0 (prefixIdent "Lin" c)
|
||||||
|
|
||||||
emptydefs = map emptydef (S.toList emptyCats)
|
emptydefs = map emptydef (S.toList emptyCats)
|
||||||
emptydef c = "lin"<>c<+>"_"<+>"="<+>"undefined"
|
emptydef c = "lin"<>c<+>"_"<+>"="<+>"undefined"
|
||||||
@@ -70,13 +73,12 @@ concrete2haskell opts gr cenv absname cnc modinfo =
|
|||||||
params1 (_,(_,rhs)) = tableTypes gr [rhs]
|
params1 (_,(_,rhs)) = tableTypes gr [rhs]
|
||||||
|
|
||||||
ppDef (Nothing,(lhs,rhs)) = hang (lhs<+>"=") 2 (convType va gId rhs)
|
ppDef (Nothing,(lhs,rhs)) = hang (lhs<+>"=") 2 (convType va gId rhs)
|
||||||
ppDef (_,(lhs,rhs)) = hang (lhs<+>"=") 2 (convert va gId' gr rhs)
|
ppDef (_,(lhs,rhs)) = hang (lhs<+>"=") 2 (convert va gId gr rhs)
|
||||||
|
|
||||||
gId :: Ident -> Doc
|
gId :: Ident -> Ident
|
||||||
gId = if haskellOption opts HaskellNoPrefix then pp else ("G"<>).pp
|
gId = if haskellOption opts HaskellNoPrefix then id else prefixIdent "G"
|
||||||
gId' = if haskellOption opts HaskellNoPrefix then id else prefixIdent "G"
|
|
||||||
va = haskellOption opts HaskellVariants
|
va = haskellOption opts HaskellVariants
|
||||||
pure = if va then brackets else pp
|
pure = if va then ListT else id
|
||||||
|
|
||||||
neededParamTypes have [] = []
|
neededParamTypes have [] = []
|
||||||
neededParamTypes have (q:qs) =
|
neededParamTypes have (q:qs) =
|
||||||
@@ -90,11 +92,7 @@ haskPreamble va absname cncname =
|
|||||||
"{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, LambdaCase #-}" $$
|
"{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, LambdaCase #-}" $$
|
||||||
"module" <+> cncname <+> "where" $$
|
"module" <+> cncname <+> "where" $$
|
||||||
"import Prelude hiding (Ordering(..))" $$
|
"import Prelude hiding (Ordering(..))" $$
|
||||||
"import Control.Applicative(Applicative,pure,empty,(<$>),(<*>))" $$
|
"import Control.Applicative((<$>),(<*>))" $$
|
||||||
--"import Data.Foldable(asum)" $$
|
|
||||||
--"import Control.Monad(join)" $$
|
|
||||||
"import qualified Data.Map as M" $$
|
|
||||||
"import Data.Map((!))" $$
|
|
||||||
"import PGF.Haskell" $$
|
"import PGF.Haskell" $$
|
||||||
"import qualified" <+> absname <+> "as A" $$
|
"import qualified" <+> absname <+> "as A" $$
|
||||||
"" $$
|
"" $$
|
||||||
@@ -125,7 +123,8 @@ toHaskell gId gr absname cenv (name,jment) =
|
|||||||
params = [(b,prefixIdent "g" x)|(b,x,_)<-ctx]
|
params = [(b,prefixIdent "g" x)|(b,x,_)<-ctx]
|
||||||
args = map snd params
|
args = map snd params
|
||||||
abs_args = map ("abs_"<>) args
|
abs_args = map ("abs_"<>) args
|
||||||
lhs = if null args then aId name else parens (aId name<+>hsep abs_args)
|
lhs = if null args then pp (aId name)
|
||||||
|
else parens (aId name<+>hsep abs_args)
|
||||||
rhs = foldr letlin e' (zip args absctx)
|
rhs = foldr letlin e' (zip args absctx)
|
||||||
letlin (a,(_,_,at)) =
|
letlin (a,(_,_,at)) =
|
||||||
Let (a,(Just (con ("Lin"++render at)),(App (con ("lin"++render at)) (con ("abs_"++render a)))))
|
Let (a,(Just (con ("Lin"++render at)),(App (con ("lin"++render at)) (con ("abs_"++render a)))))
|
||||||
@@ -135,7 +134,7 @@ toHaskell gId gr absname cenv (name,jment) =
|
|||||||
_ -> []
|
_ -> []
|
||||||
where
|
where
|
||||||
nf loc = normalForm cenv (L loc name)
|
nf loc = normalForm cenv (L loc name)
|
||||||
aId n = "A."<>gId n
|
aId n = prefixIdent "A." (gId n)
|
||||||
|
|
||||||
unAbs 0 t = t
|
unAbs 0 t = t
|
||||||
unAbs n (Abs _ _ t) = unAbs (n-1) t
|
unAbs n (Abs _ _ t) = unAbs (n-1) t
|
||||||
@@ -204,7 +203,7 @@ coerce env ty t =
|
|||||||
extend env (x,(Just ty,rhs)) = (x,ty):env
|
extend env (x,(Just ty,rhs)) = (x,ty):env
|
||||||
extend env _ = env
|
extend env _ = env
|
||||||
|
|
||||||
convert va gId gr t = pp (convert' va gId [] gr t)
|
convert va gId gr = convert' va gId [] gr
|
||||||
|
|
||||||
convert' va gId vs gr = ppT
|
convert' va gId vs gr = ppT
|
||||||
where
|
where
|
||||||
@@ -213,13 +212,12 @@ convert' va gId vs gr = ppT
|
|||||||
|
|
||||||
ppT t =
|
ppT t =
|
||||||
case t of
|
case t of
|
||||||
-- For lets inserted on the top-level by this converter:
|
-- Only for 'let' inserted on the top-level by this converter:
|
||||||
Let (x,(_,xt)) t -> let1 x (ppT0 xt) (ppT t)
|
Let (x,(_,xt)) t -> let1 x (ppT0 xt) (ppT t)
|
||||||
-- Abs b x t -> "\\"<+>x<+>"->"<+>ppT t
|
-- Abs b x t -> ...
|
||||||
-- V ty ts -> hang "table" 4 (sep [list (enumAll ty),list ts])
|
|
||||||
V ty ts -> pure (c "table" `Ap` dedup ts)
|
V ty ts -> pure (c "table" `Ap` dedup ts)
|
||||||
T (TTyped ty) cs -> pure (LambdaCase (map ppCase cs))
|
T (TTyped ty) cs -> pure (LambdaCase (map ppCase cs))
|
||||||
S t p -> join (ap (ppT t) (ppT p))
|
S t p -> select (ppT t) (ppT p)
|
||||||
C t1 t2 -> concat (ppT t1) (ppT t2)
|
C t1 t2 -> concat (ppT t1) (ppT t2)
|
||||||
App f a -> ap (ppT f) (ppT a)
|
App f a -> ap (ppT f) (ppT a)
|
||||||
R r -> aps (ppT (rcon (map fst r))) (fields r)
|
R r -> aps (ppT (rcon (map fst r))) (fields r)
|
||||||
@@ -246,18 +244,17 @@ convert' va gId vs gr = ppT
|
|||||||
Ok CAPIT -> single (c "CAPIT")
|
Ok CAPIT -> single (c "CAPIT")
|
||||||
_ -> Var n
|
_ -> Var n
|
||||||
|
|
||||||
ppAP = ppP
|
|
||||||
ppP p =
|
ppP p =
|
||||||
case p of
|
case p of
|
||||||
PC c ps -> ConP (gId c) (map ppAP ps)
|
PC c ps -> ConP (gId c) (map ppP ps)
|
||||||
PP (_,c) ps -> ConP (gId c) (map ppAP ps)
|
PP (_,c) ps -> ConP (gId c) (map ppP ps)
|
||||||
PR r -> ConP (rcon' (map fst r)) (map (ppAP.snd) (filter (not.isLockLabel.fst) r))
|
PR r -> ConP (rcon' (map fst r)) (map (ppP.snd) (filter (not.isLockLabel.fst) r))
|
||||||
PW -> WildP
|
PW -> WildP
|
||||||
PV x -> VarP x
|
PV x -> VarP x
|
||||||
PString s -> Lit (show s) -- !!
|
PString s -> Lit (show s) -- !!
|
||||||
PInt i -> Lit (show i)
|
PInt i -> Lit (show i)
|
||||||
PFloat x -> Lit (show x)
|
PFloat x -> Lit (show x)
|
||||||
PT _ p -> ppAP p
|
PT _ p -> ppP p
|
||||||
PAs x p -> AsP x (ppP p)
|
PAs x p -> AsP x (ppP p)
|
||||||
|
|
||||||
token s = single (c "TK" `Ap` lit s)
|
token s = single (c "TK" `Ap` lit s)
|
||||||
@@ -278,16 +275,18 @@ convert' va gId vs gr = ppT
|
|||||||
fields = map (ppT.snd.snd) . sort . filter (not.isLockLabel.fst)
|
fields = map (ppT.snd.snd) . sort . filter (not.isLockLabel.fst)
|
||||||
|
|
||||||
c = Const
|
c = Const
|
||||||
single x = List [x]
|
|
||||||
lit s = c (show s) -- hmm
|
lit s = c (show s) -- hmm
|
||||||
concat = if va then concat' else concat0
|
concat = if va then concat' else plusplus
|
||||||
where
|
where
|
||||||
concat0 (List ts1) (List ts2) = List (ts2++ts2)
|
|
||||||
concat0 t1 t2 =Op t1 "++" t2
|
|
||||||
concat' (List [List ts1]) (List [List ts2]) = List [List (ts1++ts2)]
|
concat' (List [List ts1]) (List [List ts2]) = List [List (ts1++ts2)]
|
||||||
concat' t1 t2 = Op t1 "+++" t2
|
concat' t1 t2 = Op t1 "+++" t2
|
||||||
pure = if va then pure' else id
|
pure = if va then single else id
|
||||||
pure' x = List [x] -- forcing the list monad
|
pure' = single -- forcing the list monad
|
||||||
|
|
||||||
|
select = if va then select' else Ap
|
||||||
|
select' (List [t]) (List [p]) = Op t "!" p
|
||||||
|
select' (List [t]) p = Op t "!$" p
|
||||||
|
select' t p = Op t "!*" p
|
||||||
|
|
||||||
ap = if va then ap' else Ap
|
ap = if va then ap' else Ap
|
||||||
where
|
where
|
||||||
@@ -295,22 +294,18 @@ convert' va gId vs gr = ppT
|
|||||||
ap' f x = Op f "<*>" x
|
ap' f x = Op f "<*>" x
|
||||||
fmap f (List [x]) = pure' (Ap f x)
|
fmap f (List [x]) = pure' (Ap f x)
|
||||||
fmap f x = Op f "<$>" x
|
fmap f x = Op f "<$>" x
|
||||||
join = if va then join' else id
|
|
||||||
where
|
-- join = if va then join' else id
|
||||||
join' (List [x]) = x
|
join' (List [x]) = x
|
||||||
join' x = c "concat" `Ap` x
|
join' x = c "concat" `Ap` x
|
||||||
|
|
||||||
empty = if va then List [] else c "error" `Ap` c (show "empty variant")
|
empty = if va then List [] else c "error" `Ap` c (show "empty variant")
|
||||||
variants = if va then \ ts -> c "concat" `Ap` List (map ppT ts)
|
variants = if va then \ ts -> join' (List (map ppT ts))
|
||||||
else \ (t:_) -> ppT t
|
else \ (t:_) -> ppT t
|
||||||
|
|
||||||
aps f [] = f
|
aps f [] = f
|
||||||
aps f (a:as) = aps (ap f a) as
|
aps f (a:as) = aps (ap f a) as
|
||||||
|
|
||||||
-- enumAll ty = case allParamValues gr ty of Ok ts -> ts
|
|
||||||
|
|
||||||
-- list = brackets . fsep . punctuate "," . map ppT
|
|
||||||
-- list' = brackets . fsep . punctuate ","
|
|
||||||
|
|
||||||
dedup ts =
|
dedup ts =
|
||||||
if M.null dups
|
if M.null dups
|
||||||
then List (map ppT ts)
|
then List (map ppT ts)
|
||||||
@@ -331,38 +326,22 @@ patVars p =
|
|||||||
PAs x p -> x:patVars p
|
PAs x p -> x:patVars p
|
||||||
_ -> collectPattOp patVars p
|
_ -> collectPattOp patVars p
|
||||||
|
|
||||||
convType = convType' False
|
convType va gId = ppT
|
||||||
convTypeA = convType' True
|
|
||||||
|
|
||||||
convType' atomic va gId = if atomic then ppA else ppT
|
|
||||||
where
|
where
|
||||||
ppT = ppT' False
|
ppT t =
|
||||||
ppT' loop t =
|
|
||||||
case t of
|
case t of
|
||||||
Table ti tv -> ppB ti <+> "->" <+>
|
Table ti tv -> Fun (ppT ti) (if va then ListT (ppT tv) else ppT tv)
|
||||||
if va then brackets (ppT tv) else ppT tv
|
RecType rt -> tcon (rcon' (map fst rt)) (fields rt)
|
||||||
_ -> ppB' loop t
|
App tf ta -> TAp (ppT tf) (ppT ta)
|
||||||
|
FV [] -> tcon0 (identS "({-empty variant-})")
|
||||||
|
Sort k -> tcon0 k
|
||||||
|
EInt n -> tcon0 (identS ("({-"++show n++"-})")) -- type level numeric literal
|
||||||
|
FV (t:ts) -> ppT t -- !!
|
||||||
|
QC (m,n) -> tcon0 (gId (qual m n))
|
||||||
|
Q (m,n) -> tcon0 (gId (qual m n))
|
||||||
|
_ -> error $ "Missing case in convType for: "++show t
|
||||||
|
|
||||||
ppB = ppB' False
|
fields = map (ppT.snd) . sort . filter (not.isLockLabel.fst)
|
||||||
ppB' loop t =
|
|
||||||
case t of
|
|
||||||
RecType rt -> rcon (map fst rt)<+>fsep (fields rt)
|
|
||||||
App tf ta -> ppB tf <+> ppA ta
|
|
||||||
FV [] -> pp "({-empty variant-})"
|
|
||||||
_ -> ppA' loop t
|
|
||||||
|
|
||||||
ppA = ppA' False
|
|
||||||
ppA' True t = error $ "Missing case in convType for: "++show t
|
|
||||||
ppA' loop t =
|
|
||||||
case t of
|
|
||||||
Sort k -> pp k
|
|
||||||
EInt n -> parens ("{-"<>n<>"-}") -- type level numeric literal
|
|
||||||
FV (t:ts) -> "{-variants-}"<>ppA t -- !!
|
|
||||||
QC (m,n) -> gId (qual m n)
|
|
||||||
Q (m,n) -> gId (qual m n)
|
|
||||||
_ -> {-trace (show t) $-} parens (ppT' True t)
|
|
||||||
|
|
||||||
fields = map (ppA.snd) . sort . filter (not.isLockLabel.fst)
|
|
||||||
|
|
||||||
proj l = con ("proj_"++render l)
|
proj l = con ("proj_"++render l)
|
||||||
rcon = con . rcon_name
|
rcon = con . rcon_name
|
||||||
@@ -374,9 +353,11 @@ recordType ls =
|
|||||||
"data"<+>app<+>"="<+>app <+> "deriving (Eq,Ord,Show)" $$
|
"data"<+>app<+>"="<+>app <+> "deriving (Eq,Ord,Show)" $$
|
||||||
enumAllInstance $$
|
enumAllInstance $$
|
||||||
vcat (zipWith projection vs ls) $$
|
vcat (zipWith projection vs ls) $$
|
||||||
to_rcon ls<+>"r"<+>"="<+>cn<+>fsep [parens (proj l<+>"r")|l<-ls] $$ ""
|
hang (to_rcon ls<+>"r"<+>"=") 4
|
||||||
|
(cn<+>fsep [parens (proj l<+>"r")|l<-ls]) $$ ""
|
||||||
where
|
where
|
||||||
cn = rcon ls
|
cn = rcon ls
|
||||||
|
cn' = rcon' ls
|
||||||
-- Not all record labels are syntactically correct as type variables in Haskell
|
-- Not all record labels are syntactically correct as type variables in Haskell
|
||||||
-- app = cn<+>ls
|
-- app = cn<+>ls
|
||||||
app = cn<+>hsep vs -- don't reuse record labels
|
app = cn<+>hsep vs -- don't reuse record labels
|
||||||
@@ -389,7 +370,7 @@ recordType ls =
|
|||||||
|
|
||||||
enumAllInstance =
|
enumAllInstance =
|
||||||
hang ("instance"<+>ctx<+>"EnumAll"<+>parens app<+>"where") 4
|
hang ("instance"<+>ctx<+>"EnumAll"<+>parens app<+>"where") 4
|
||||||
("enumAll"<+>"="<+>enumCon cn n)
|
(hang ("enumAll"<+>"=") 4 (enumCon cn' n))
|
||||||
where
|
where
|
||||||
ctx = if n==0
|
ctx = if n==0
|
||||||
then empty
|
then empty
|
||||||
@@ -404,11 +385,11 @@ paramType va gId gr q@(_,n) =
|
|||||||
Ok (m,ResParam (Just (L _ ps)) _)
|
Ok (m,ResParam (Just (L _ ps)) _)
|
||||||
{- - | m/=cPredef && m/=moduleNameS "Prelude"-} ->
|
{- - | m/=cPredef && m/=moduleNameS "Prelude"-} ->
|
||||||
((S.singleton (m,n),argTypes ps),
|
((S.singleton (m,n),argTypes ps),
|
||||||
"data"<+>gId (qual m n)<+>"="<+>
|
hang ("data"<+>gId (qual m n)<+>"=") 7
|
||||||
sep [fsep (punctuate " |" (map (param m) ps)),
|
(sep [fsep (punctuate " |" (map (param m) ps)),
|
||||||
pp "deriving (Eq,Ord,Show)"] $$
|
pp "deriving (Eq,Ord,Show)"]) $$
|
||||||
hang ("instance EnumAll"<+>gId (qual m n)<+>"where") 4
|
hang ("instance EnumAll"<+>gId (qual m n)<+>"where") 4
|
||||||
("enumAll"<+>"="<+>sep (punctuate " ++" (map (enumParam m) ps)))
|
("enumAll"<+>"="<+>foldr1 plusplus (map (enumParam m) ps))
|
||||||
)
|
)
|
||||||
Ok (m,ResOper _ (Just (L _ t)))
|
Ok (m,ResOper _ (Just (L _ t)))
|
||||||
| m==cPredef && n==cInts ->
|
| m==cPredef && n==cInts ->
|
||||||
@@ -419,7 +400,7 @@ paramType va gId gr q@(_,n) =
|
|||||||
"type"<+>gId (qual m n)<+>"="<+>convType va gId t)
|
"type"<+>gId (qual m n)<+>"="<+>convType va gId t)
|
||||||
_ -> ((S.empty,S.empty),empty)
|
_ -> ((S.empty,S.empty),empty)
|
||||||
where
|
where
|
||||||
param m (n,ctx) = gId (qual m n)<+>[convTypeA va gId t|(_,_,t)<-ctx]
|
param m (n,ctx) = tcon (gId (qual m n)) [convType va gId t|(_,_,t)<-ctx]
|
||||||
argTypes = S.unions . map argTypes1
|
argTypes = S.unions . map argTypes1
|
||||||
argTypes1 (n,ctx) = S.unions [paramTypes gr t|(_,_,t)<-ctx]
|
argTypes1 (n,ctx) = S.unions [paramTypes gr t|(_,_,t)<-ctx]
|
||||||
|
|
||||||
@@ -427,9 +408,11 @@ paramType va gId gr q@(_,n) =
|
|||||||
|
|
||||||
enumCon name arity =
|
enumCon name arity =
|
||||||
if arity==0
|
if arity==0
|
||||||
then brackets name
|
then single (Var name)
|
||||||
else parens $
|
else foldl ap (single (Var name)) (replicate arity (Const "enumAll"))
|
||||||
fsep ((name<+>"<$>"):punctuate " <*>" (replicate arity (pp "enumAll")))
|
where
|
||||||
|
ap (List [f]) a = Op f "<$>" a
|
||||||
|
ap f a = Op f "<*>" a
|
||||||
|
|
||||||
qual :: ModuleName -> Ident -> Ident
|
qual :: ModuleName -> Ident -> Ident
|
||||||
qual m = prefixIdent (render m++"_")
|
qual m = prefixIdent (render m++"_")
|
||||||
@@ -437,12 +420,42 @@ qual m = prefixIdent (render m++"_")
|
|||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- ** A Haskell subset
|
-- ** A Haskell subset
|
||||||
|
|
||||||
|
data Ty = TId Ident | TAp Ty Ty | Fun Ty Ty | ListT Ty
|
||||||
|
|
||||||
data Exp = Var Ident | Const String | Ap Exp Exp | Op Exp String Exp
|
data Exp = Var Ident | Const String | Ap Exp Exp | Op Exp String Exp
|
||||||
| List [Exp] | Pair Exp Exp
|
| List [Exp] | Pair Exp Exp
|
||||||
| Lets [(Ident,Exp)] Exp | LambdaCase [(Pat,Exp)]
|
| Lets [(Ident,Exp)] Exp | LambdaCase [(Pat,Exp)]
|
||||||
|
|
||||||
data Pat = WildP | VarP Ident | Lit String | ConP Ident [Pat] | AsP Ident Pat
|
data Pat = WildP | VarP Ident | Lit String | ConP Ident [Pat] | AsP Ident Pat
|
||||||
|
|
||||||
|
tvar = TId
|
||||||
|
tcon0 = TId
|
||||||
|
tcon c = foldl TAp (TId c)
|
||||||
|
|
||||||
let1 x xe e = Lets [(x,xe)] e
|
let1 x xe e = Lets [(x,xe)] e
|
||||||
|
single x = List [x]
|
||||||
|
|
||||||
|
plusplus (List ts1) (List ts2) = List (ts1++ts2)
|
||||||
|
plusplus (List [t]) t2 = Op t ":" t2
|
||||||
|
plusplus t1 t2 = Op t1 "++" t2
|
||||||
|
|
||||||
|
instance Pretty Ty where
|
||||||
|
pp = ppT
|
||||||
|
where
|
||||||
|
ppT t = case flatFun t of t:ts -> sep (ppB t:["->"<+>ppB t|t<-ts])
|
||||||
|
ppB t = case flatTAp t of t:ts -> ppA t<+>sep (map ppA ts)
|
||||||
|
|
||||||
|
ppA t =
|
||||||
|
case t of
|
||||||
|
TId c -> pp c
|
||||||
|
ListT t -> brackets t
|
||||||
|
_ -> parens t
|
||||||
|
|
||||||
|
flatFun (Fun t1 t2) = t1:flatFun t2 -- right associative
|
||||||
|
flatFun t = [t]
|
||||||
|
|
||||||
|
flatTAp (TAp t1 t2) = flatTAp t1++[t2] -- left associative
|
||||||
|
flatTAp t = [t]
|
||||||
|
|
||||||
instance Pretty Exp where
|
instance Pretty Exp where
|
||||||
pp = ppT
|
pp = ppT
|
||||||
@@ -454,10 +467,9 @@ instance Pretty Exp where
|
|||||||
"in" <+>e]
|
"in" <+>e]
|
||||||
LambdaCase alts -> hang "\\case" 4 (vcat [p<+>"->"<+>e|(p,e)<-alts])
|
LambdaCase alts -> hang "\\case" 4 (vcat [p<+>"->"<+>e|(p,e)<-alts])
|
||||||
_ -> ppB e
|
_ -> ppB e
|
||||||
ppB e =
|
|
||||||
case e of
|
ppB e = case flatAp e of f:as -> hang (ppA f) 2 (sep (map ppA as))
|
||||||
Ap f a -> hang (ppB f) 2 (ppA a)
|
|
||||||
_ -> ppA e
|
|
||||||
ppA e =
|
ppA e =
|
||||||
case e of
|
case e of
|
||||||
Var x -> pp x
|
Var x -> pp x
|
||||||
@@ -466,6 +478,9 @@ instance Pretty Exp where
|
|||||||
List es -> brackets (fsep (punctuate "," es))
|
List es -> brackets (fsep (punctuate "," es))
|
||||||
_ -> parens e
|
_ -> parens e
|
||||||
|
|
||||||
|
flatAp (Ap t1 t2) = flatAp t1++[t2] -- left associative
|
||||||
|
flatAp t = [t]
|
||||||
|
|
||||||
instance Pretty Pat where
|
instance Pretty Pat where
|
||||||
pp = ppP
|
pp = ppP
|
||||||
where
|
where
|
||||||
|
|||||||
Reference in New Issue
Block a user