Permalink
Browse files

True definitions type.

  • Loading branch information...
1 parent 72a2b54 commit 42cc1b1d432aa8c7083811fa3b5b3355f74a6934 Sebastiaan Visser committed Dec 20, 2009
Showing with 137 additions and 171 deletions.
  1. +31 −21 src/Compiler/FreeVariables.hs
  2. +12 −12 src/Compiler/Instantiate.hs
  3. +43 −30 src/Compiler/LiftDefinitions.hs
  4. +8 −8 src/Compiler/Pipeline.hs
  5. +21 −65 src/Compiler/Raw.hs
  6. +22 −35 src/test.js
View
52 src/Compiler/FreeVariables.hs
@@ -1,55 +1,65 @@
module Compiler.FreeVariables
( FreeVarA (..)
, ExprFV
-, annotateWithFreeVariables
-, printDefinitionsWithFreeVariables
+, annotateExpression
+, annotateDefinitions
+, dump
)
where
import Compiler.Generics
-import Compiler.LiftDefinitions
import Compiler.Raw
import Control.Arrow hiding (app)
import Data.List (intercalate)
import Data.Set hiding (map, insert)
-import qualified Data.Map as M
+import Compiler.LiftDefinitions (DefinitionsA (..), Definitions)
data FreeVarA f a = FreeVarA { free :: Set String , expr :: f a }
type ExprFV = FixA FreeVarA ExprF
-annotateWithFreeVariables :: Arrow (~>) => Expr ~> ExprFV
-annotateWithFreeVariables = arr ow
+annotateExpression :: Arrow (~>) => Set String -> Expr ~> ExprFV
+annotateExpression globs = arr ow
where
ow ex = rec ex
where
- -- references to global definitions don't count as free variables.
- globs = fromList (M.keys (collectDefinitions ex))
-
-- traversal function
ann (App l r) = ae (union (fv l') (fv r')) (App l' r') where l' = rec l; r' = rec r
ann (Con c) = ae (empty) (Con c )
ann (Prim s vs) = ae (fromList vs) (Prim s vs )
ann (Lam x e) = ae (fv e' `difference` fromList x) (Lam x e' ) where e' = rec e
ann (Var v) = ae (singleton v `difference` globs) (Var v )
- ann (Def n e) = ae (fv e') (Def n e' ) where e' = rec e
- ann (More es) = ae (empty) (More es' ) where es' = map rec es
+ ann (Name n e) = ae (fv e') (Name n e' ) where e' = rec e
-- helpers
rec = ann . unId . out
ae vs e = In (FreeVarA vs e)
fv = free . out
-printDefinitionsWithFreeVariables :: Arrow (~>) => ExprFV ~> String
-printDefinitionsWithFreeVariables = arr top
+type DefinitionsFV = DefinitionsA FreeVarA
+
+annotateDefinitions :: Arrow (~>) => Definitions ~> DefinitionsFV
+annotateDefinitions = arr $ \(Defs ds m) ->
+ let globs = fromList (map fst ds)
+ ann = annotateExpression globs
+ in Defs (map (fmap ann) ds) (ann m)
+
+dump :: Arrow (~>) => DefinitionsFV ~> String
+dump = arr def
where
- top (In (FreeVarA vf x)) = (if size vf /= 0 then "/* free: " ++ show (toList vf) ++ " */" else "/* 0 */") ++ tr x
- tr (App f e) = top f ++ "(" ++ top e ++ ")"
- tr (Con c) = c
- tr (Prim s vf) = s vf
- tr (Lam as e) = "(function (" ++ intercalate ", " as ++ ")" ++ "{ " ++ "return " ++ top e ++ ";" ++ " })"
- tr (Var v) = v
- tr (Def n e) = n ++ " = " ++ top e
- tr (More es) = intercalate "\n" (map top es)
+ def (Defs ds m) = intercalate "\n" (map single (ds ++ [("__main", m)]))
+ single (d, e) = d ++ " = " ++ rec e
+
+ tr (App f e ) = rec f ++ "(" ++ rec e ++ ")"
+ tr (Con c ) = c
+ tr (Prim s vf) = s vf
+ tr (Lam as e) = "function (" ++ intercalate ", " as ++ ") { return " ++ rec e ++ ";" ++ " }"
+ tr (Var v ) = v
+ tr (Name n e ) = "/* " ++ n ++ " */ " ++ rec e
+
+ rec (In (FreeVarA vf x)) =
+ if size vf /= 0
+ then "/* free: " ++ show (toList vf) ++ " */" ++ tr x
+ else "/* 0 */" ++ tr x
View
24 src/Compiler/Instantiate.hs
@@ -1,4 +1,4 @@
-module Compiler.Instantiate (instantiateLambas, printAnonymousExpression) where
+module Compiler.Instantiate (instantiateLambas, printExpression) where
import Compiler.Generics
import Compiler.Raw
@@ -14,21 +14,21 @@ instantiateLambas = arr (flip runReader 0 . tr)
tr :: V.Val l i -> Reader Integer Expr
tr (V.App f a) = app <$> tr f <*> tr a
tr (V.Con c) = pure (con c)
- tr (V.Prim s vs) = pure (prim s vs)
tr (V.Lam f) = local (+1) (ask >>= \r -> let v = 'v':show r in lam [v] <$> tr (f (V.Var v)))
+ tr (V.Name n e) = name n <$> tr e
+ tr (V.Prim s vs) = pure (prim s vs)
tr (V.Var v) = pure (var v)
- tr (V.Name n e) = def n <$> tr e
-printAnonymousExpression :: Arrow (~>) => Expr ~> String
-printAnonymousExpression = arr tr
+printExpression :: Arrow (~>) => Expr ~> String
+printExpression = arr rec
where
- tr (In (Id (App f e))) = tr f ++ "(\n" ++ indent (tr e) ++ ")"
- tr (In (Id (Con c))) = c
- tr (In (Id (Prim s vs))) = s vs ++ " /* free: " ++ intercalate ", " vs ++ " */"
- tr (In (Id (Lam as e))) = "(function (" ++ intercalate ", " as ++ ")" ++ "\n{\n" ++ indent ("return " ++ tr e ++ ";") ++ "\n})"
- tr (In (Id (Var v))) = v
- tr (In (Id (Def n e))) = "/* " ++ n ++ "*/ " ++ tr e
- tr (In (Id (More es))) = intercalate "\n" (map tr es)
+ tr (App f e) = rec f ++ "(\n" ++ indent (rec e) ++ ")"
+ tr (Con c) = c
+ tr (Lam as e) = "(function (" ++ intercalate ", " as ++ ")" ++ "\n{\n" ++ indent ("return " ++ rec e ++ ";") ++ "\n})"
+ tr (Name n e) = "/* " ++ n ++ "*/ " ++ rec e
+ tr (Prim s vs) = s vs ++ " /* free: " ++ intercalate ", " vs ++ " */"
+ tr (Var v) = v
+ rec = tr . unId . out
indent = unlines . map (" "++) . lines
View
73 src/Compiler/LiftDefinitions.hs
@@ -1,53 +1,66 @@
module Compiler.LiftDefinitions
-( inlineDefinitions
-, collectDefinitions
-, liftDefinitions
-, printDefinitions
+( DefTable
+, DefinitionsA (..)
+, Definitions
+, inline
+, collect
+, lift
+, dump
)
where
import Compiler.Generics
import Compiler.Raw
-import Data.Map (Map, singleton, empty, elems)
import Control.Arrow hiding (app)
import Data.List (intercalate)
--- All named definitions within expression will be replaces by a variables with
--- the name of the definitions.
+type DefTable a = [(String, FixA a ExprF)]
-inlineDefinitions :: Expr -> Expr
-inlineDefinitions = foldId (In . Id . fmap defs)
+data DefinitionsA a = Defs
+ { definitions :: DefTable a
+ , expression :: FixA a ExprF
+ }
+
+type Definitions = DefinitionsA Id
+
+-- All named sub-expressions will be replaces by a variables that references
+-- the definition that will be created. All named sub-expression MUST NOT
+-- contain any free variables.
+
+inline :: Expr -> Expr
+inline = foldId (In . Id . fmap defs)
where
- defs (In (Id (Def n _))) = var n
- defs e = e
+ defs (In (Id (Name n _))) = var n
+ defs e = e
-- Collect all definitions from an expression tree and return a map with
-- name/definition pairs. Because of the Map datatype all duplicate definitions
-- will be joined to a single one.
-collectDefinitions :: Expr -> Map String Expr
-collectDefinitions = reduce defs
+collect :: Expr -> DefTable Id
+collect = reduce defs
where
- defs d@(Def n _) = singleton n (In (Id d))
- defs _ = empty
+ defs d@(Name n _) = [(n, In (Id d))]
+ defs _ = []
-- Lift all definitions to the top-level and inline all references to these
--- definitions.
+-- definitions in the main expression.
-liftDefinitions :: Arrow (~>) => Expr ~> Expr
-liftDefinitions = arr (\e -> more (elems (collectDefinitions e) ++ [def "__main" (tr e)]))
- where
- tr d@(In (Id (Def _ _))) = d
- tr e = inlineDefinitions e
+lift :: Arrow (~>) => Expr ~> Definitions
+lift = arr (uncurry Defs . (collect &&& inline))
-printDefinitions :: Arrow (~>) => Expr ~> String
-printDefinitions = arr tr
+dump :: Arrow (~>) => Definitions ~> String
+dump = arr def
where
- tr (In (Id (App f e))) = tr f ++ "(" ++ tr e ++ ")"
- tr (In (Id (Con c))) = c
- tr (In (Id (Prim s vf))) = s vf
- tr (In (Id (Lam as e))) = "function (" ++ intercalate ", " as ++ ") { return " ++ tr e ++ ";" ++ " }"
- tr (In (Id (Var v))) = v
- tr (In (Id (Def n e))) = n ++ " = " ++ tr e
- tr (In (Id (More es))) = intercalate "\n" (map tr es)
+ def (Defs ds m) = intercalate "\n" (map single (ds ++ [("__main", m)]))
+ single (d, e) = d ++ " = " ++ rec e
+
+ tr (App f e ) = rec f ++ "(" ++ rec e ++ ")"
+ tr (Con c ) = c
+ tr (Prim s vf) = s vf
+ tr (Lam as e) = "function (" ++ intercalate ", " as ++ ") { return " ++ rec e ++ ";" ++ " }"
+ tr (Var v ) = v
+ tr (Name n e ) = "/* " ++ n ++ " */ " ++ rec e
+
+ rec = tr . unId . out
View
16 src/Compiler/Pipeline.hs
@@ -1,21 +1,21 @@
{-# LANGUAGE Arrows #-}
module Compiler.Pipeline where
-import Compiler.FreeVariables
import Compiler.Instantiate
-import Compiler.LiftDefinitions
-import Compiler.LiftClosures
--- import Compiler.LiftLambdas
import Control.Arrow
import Lang.Value
+import qualified Compiler.FreeVariables as FreeVariables
+import qualified Compiler.LiftDefinitions as Definitions
+-- import Compiler.LiftClosures
+-- import Compiler.LiftLambdas
compiler :: Val l i -> IO String
compiler = runKleisli
$ instantiateLambas
- >>> liftDefinitions
- >>> annotateWithFreeVariables
- >>> liftClosures
- >>> printDefinitions
+ >>> Definitions.lift
+ >>> FreeVariables.annotateDefinitions
+-- >>> liftClosures
+ >>> FreeVariables.dump
-- >>> addLambdaAbstractions
-- >>> collectSuperCombinators
View
86 src/Compiler/Raw.hs
@@ -8,91 +8,47 @@
module Compiler.Raw where
import Compiler.Generics
-import Control.Applicative
import Control.Monad.State
import Data.Foldable hiding (elem, mapM_, concatMap, concat, foldr)
-import Data.Map (Map, lookup)
-import Data.Maybe
-import Data.Monoid
import Data.Traversable hiding (mapM)
import Prelude hiding (lookup)
-import qualified Data.Reify as R
-import qualified Data.Set as Set
-- Raw value datatype.
-
+
+type Con = String
+type Name = String
+type Var = String
+type Body = [Var] -> String
+
data ExprF f =
App f f
- | Con String
- | Prim ([String] -> String) [String]
- | Lam [String] f
- | Var String
- | Def String f
- | More [f]
+ | Con Con
+ | Lam [Var] f
+ | Name String f
+ | Prim Body [Var]
+ | Var Var
deriving (Functor, Foldable, Traversable)
-type Expr = Fix ExprF
+type ExprA a = FixA a ExprF
+type Expr = Fix ExprF
-- Smart constructors.
app :: Expr -> Expr -> Expr
app a b = In (Id (App a b))
-con :: String -> Expr
+con :: Con -> Expr
con a = In (Id (Con a))
-prim :: ([String] -> String) -> [String] -> Expr
-prim f as = In (Id (Prim f as))
-
-lam :: [String] -> Expr -> Expr
+lam :: [Var] -> Expr -> Expr
lam as f = In (Id (Lam as f))
-var :: String -> Expr
-var a = In (Id (Var a))
-
-def :: String -> Expr -> Expr
-def a b = In (Id (Def a b))
+name :: Name -> Expr -> Expr
+name a b = In (Id (Name a b))
-more :: [Expr] -> Expr
-more as = In (Id (More as))
-
--- MuRef instances for Data.Reify.
-
-instance Traversable f => R.MuRef (FixA Id f) where
- type R.DeRef (Fix f) = f
- mapDeRef f = traverse f . unId . out
-
-data Graph = Graph
- { nodes :: Map String (ExprF String)
- , first :: String
- }
-
--- Generic value traversal.
+prim :: Body -> [Var] -> Expr
+prim f as = In (Id (Prim f as))
-foldGraph
- :: (Graph -> [a] -> [a] -> String -> String -> String -> a)
- -> (Graph -> String -> String -> a)
- -> (Graph -> String -> ([String] -> String) -> [String] -> a)
- -> (Graph -> [a] -> String -> [String] -> String -> a)
- -> (Graph -> String -> String -> a)
- -> (Graph -> [a] -> String -> String -> String -> a)
- -> (Graph -> [[a]] -> String -> [String] -> a)
- -> Graph
- -> [a]
-foldGraph f0 f1 f2 f3 f4 f5 f6 g@(Graph m r) = evalState (folder (r, r `from` m)) Set.empty
- where
- folder (i, term) =
- case term of
- App f b -> rec f >>= \r0 -> rec b >>= \r1 -> pure [f0 g r0 r1 i f b ]
- Con s -> pure [f1 g i s ]
- Prim s vs -> pure [f2 g i s vs ]
- Lam v b -> rec b >>= \r0 -> pure [f3 g r0 i v b ]
- Var v -> pure [f4 g i v ]
- More as -> mapM rec as >>= \rs -> pure [f6 g rs i as ]
- Def n b -> rec b >>= \r0 -> pure [f5 g r0 i n b ]
- from f = fromMaybe (error "internal error in foldGraph") . lookup f
- rec k =
- do v <- gets (Set.member k)
- modify (Set.insert k)
- if not v then folder (k, k `from` m) else return mempty
+var :: Var -> Expr
+var a = In (Id (Var a))
View
57 src/test.js
@@ -1,35 +1,22 @@
-add = function (v5) { return function (v6) { return v5 + v6; }; }
-bool = function (v5) { return function (v6) { return function (v7) { return v7 ? v5(/*force*/) : v6(/*force*/); }; }; }
-cons = function (v6) { return function (v7) { return { head : v6, tail : v7 }; }; }
-eq = function (v5) { return function (v6) { return v5 == v6; }; }
-fix = function (v1) { return fix = arguments.callee, v1(function (i) { return fix(v1)(i) }); }
-just = function (v1) { return { just : v1 }; }
-list = function (v3) { return function (v4) { return function (v5) { return v5.nil ? v3 : v4(v5.head)(v5.tail); }; }; }
-maybe = function (v1) { return function (v2) { return function (v3) { return v3.nothing ? v1 : v2(v3.just); }; }; }
-mul = function (v1) { return function (v2) { return v1 * v2; }; }
-sub = function (v6) { return function (v7) { return v6 - v7; }; }
-c1 = list(0)
-c2 = fix(function (v1) { return function (v2) { return c1(function (v3) { return function (v4) { return add(v3)(v1(v4)); }; })(v2); }; })
-c3 = function (v6) { return function (v7) { return v6; }; }({ nil : 1 })
-c4 = bool(function (v5) { return c3(v5); })
-c5 = cons(8)
-c6 = fix(function (v3) { return function (v4) { return c4(function (v5) { return function (v6) { return function (v7) { return v6; }; }(c5(v3(sub(v4)(1))))(v5); })(eq(v4)(0)); }; })
-c7 = c6(3)
-c8 = list(c7)
-c9 = fix(function (v1) { return function (v2) { return c8(function (v3) { return function (v4) { return cons(v3)(v1(v4)); }; })(v2); }; })
-c10 = function (v4) { return function (v5) { return v4; }; }({ nil : 1 })
-c11 = bool(function (v3) { return c10(v3); })
-c12 = cons(8)
-c13 = fix(function (v1) { return function (v2) { return c11(function (v3) { return function (v4) { return function (v5) { return v4; }; }(c12(v1(sub(v2)(1))))(v3); })(eq(v2)(0)); }; })
-c14 = c13(3)
-c15 = c9(c14)
-c16 = c2(c15)
-c17 = mul(c16)
-c18 = maybe(4)
-c19 = c18(function (v1) { return mul(v1)(8); })
-c20 = sub(3)
-c21 = c20(2)
-c22 = just(c21)
-c23 = c19(c22)
-c24 = c17(c23)
-__main = c24
+mul = /* 0 *//* mul */ /* 0 */function (v1) { return /* free: ["v1"] */function (v2) { return /* free: ["v1","v2"] */v1 * v2; }; }
+fix = /* 0 *//* fix */ /* 0 */function (v1) { return /* free: ["v1"] */fix = arguments.callee, v1(function (i) { return fix(v1)(i) }); }
+list = /* 0 *//* list */ /* 0 */function (v3) { return /* free: ["v3"] */function (v4) { return /* free: ["v3","v4"] */function (v5) { return /* free: ["v3","v4","v5"] */v5.nil ? v3 : v4(v5.head)(v5.tail); }; }; }
+add = /* 0 *//* add */ /* 0 */function (v5) { return /* free: ["v5"] */function (v6) { return /* free: ["v5","v6"] */v5 + v6; }; }
+fix = /* 0 *//* fix */ /* 0 */function (v1) { return /* free: ["v1"] */fix = arguments.callee, v1(function (i) { return fix(v1)(i) }); }
+list = /* 0 *//* list */ /* 0 */function (v3) { return /* free: ["v3"] */function (v4) { return /* free: ["v3","v4"] */function (v5) { return /* free: ["v3","v4","v5"] */v5.nil ? v3 : v4(v5.head)(v5.tail); }; }; }
+fix = /* 0 *//* fix */ /* 0 */function (v3) { return /* free: ["v3"] */fix = arguments.callee, v3(function (i) { return fix(v3)(i) }); }
+bool = /* 0 *//* bool */ /* 0 */function (v5) { return /* free: ["v5"] */function (v6) { return /* free: ["v5","v6"] */function (v7) { return /* free: ["v5","v6","v7"] */v7 ? v5(/*force*/) : v6(/*force*/); }; }; }
+cons = /* 0 *//* cons */ /* 0 */function (v6) { return /* free: ["v6"] */function (v7) { return /* free: ["v6","v7"] */{ head : v6, tail : v7 }; }; }
+sub = /* 0 *//* sub */ /* 0 */function (v6) { return /* free: ["v6"] */function (v7) { return /* free: ["v6","v7"] */v6 - v7; }; }
+eq = /* 0 *//* eq */ /* 0 */function (v5) { return /* free: ["v5"] */function (v6) { return /* free: ["v5","v6"] */v5 == v6; }; }
+cons = /* 0 *//* cons */ /* 0 */function (v5) { return /* free: ["v5"] */function (v6) { return /* free: ["v5","v6"] */{ head : v5, tail : v6 }; }; }
+fix = /* 0 *//* fix */ /* 0 */function (v1) { return /* free: ["v1"] */fix = arguments.callee, v1(function (i) { return fix(v1)(i) }); }
+bool = /* 0 *//* bool */ /* 0 */function (v3) { return /* free: ["v3"] */function (v4) { return /* free: ["v3","v4"] */function (v5) { return /* free: ["v3","v4","v5"] */v5 ? v3(/*force*/) : v4(/*force*/); }; }; }
+cons = /* 0 *//* cons */ /* 0 */function (v4) { return /* free: ["v4"] */function (v5) { return /* free: ["v4","v5"] */{ head : v4, tail : v5 }; }; }
+sub = /* 0 *//* sub */ /* 0 */function (v4) { return /* free: ["v4"] */function (v5) { return /* free: ["v4","v5"] */v4 - v5; }; }
+eq = /* 0 *//* eq */ /* 0 */function (v3) { return /* free: ["v3"] */function (v4) { return /* free: ["v3","v4"] */v3 == v4; }; }
+maybe = /* 0 *//* maybe */ /* 0 */function (v1) { return /* free: ["v1"] */function (v2) { return /* free: ["v1","v2"] */function (v3) { return /* free: ["v1","v2","v3"] */v3.nothing ? v1 : v2(v3.just); }; }; }
+mul = /* 0 *//* mul */ /* 0 */function (v2) { return /* free: ["v2"] */function (v3) { return /* free: ["v2","v3"] */v2 * v3; }; }
+just = /* 0 *//* just */ /* 0 */function (v1) { return /* free: ["v1"] */{ just : v1 }; }
+sub = /* 0 *//* sub */ /* 0 */function (v1) { return /* free: ["v1"] */function (v2) { return /* free: ["v1","v2"] */v1 - v2; }; }
+__main = /* 0 *//* 0 *//* 0 */mul(/* 0 *//* 0 *//* 0 */fix(/* 0 */function (v1) { return /* free: ["v1"] */function (v2) { return /* free: ["v1","v2"] *//* free: ["v1"] *//* 0 *//* 0 */list(/* 0 */0)(/* free: ["v1"] */function (v3) { return /* free: ["v1","v3"] */function (v4) { return /* free: ["v1","v3","v4"] *//* free: ["v3"] *//* 0 */add(/* free: ["v3"] */v3)(/* free: ["v1","v4"] *//* free: ["v1"] */v1(/* free: ["v4"] */v4)); }; })(/* free: ["v2"] */v2); }; })(/* 0 *//* 0 *//* 0 */fix(/* 0 */function (v1) { return /* free: ["v1"] */function (v2) { return /* free: ["v1","v2"] *//* free: ["v1"] *//* 0 *//* 0 */list(/* 0 *//* 0 *//* 0 */fix(/* 0 */function (v3) { return /* free: ["v3"] */function (v4) { return /* free: ["v3","v4"] *//* free: ["v3","v4"] *//* 0 *//* 0 */bool(/* 0 */function (v5) { return /* free: ["v5"] *//* 0 *//* 0 */function (v6) { return /* free: ["v6"] */function (v7) { return /* free: ["v6"] */v6; }; }(/* 0 */{ nil : 1 })(/* free: ["v5"] */v5); })(/* free: ["v3","v4"] */function (v5) { return /* free: ["v3","v4","v5"] *//* free: ["v3","v4"] *//* 0 */function (v6) { return /* free: ["v6"] */function (v7) { return /* free: ["v6"] */v6; }; }(/* free: ["v3","v4"] *//* 0 *//* 0 */cons(/* 0 */8)(/* free: ["v3","v4"] *//* free: ["v3"] */v3(/* free: ["v4"] *//* free: ["v4"] *//* 0 */sub(/* free: ["v4"] */v4)(/* 0 */1))))(/* free: ["v5"] */v5); })(/* free: ["v4"] *//* free: ["v4"] *//* 0 */eq(/* free: ["v4"] */v4)(/* 0 */0)); }; })(/* 0 */3))(/* free: ["v1"] */function (v3) { return /* free: ["v1","v3"] */function (v4) { return /* free: ["v1","v3","v4"] *//* free: ["v3"] *//* 0 */cons(/* free: ["v3"] */v3)(/* free: ["v1","v4"] *//* free: ["v1"] */v1(/* free: ["v4"] */v4)); }; })(/* free: ["v2"] */v2); }; })(/* 0 *//* 0 *//* 0 */fix(/* 0 */function (v1) { return /* free: ["v1"] */function (v2) { return /* free: ["v1","v2"] *//* free: ["v1","v2"] *//* 0 *//* 0 */bool(/* 0 */function (v3) { return /* free: ["v3"] *//* 0 *//* 0 */function (v4) { return /* free: ["v4"] */function (v5) { return /* free: ["v4"] */v4; }; }(/* 0 */{ nil : 1 })(/* free: ["v3"] */v3); })(/* free: ["v1","v2"] */function (v3) { return /* free: ["v1","v2","v3"] *//* free: ["v1","v2"] *//* 0 */function (v4) { return /* free: ["v4"] */function (v5) { return /* free: ["v4"] */v4; }; }(/* free: ["v1","v2"] *//* 0 *//* 0 */cons(/* 0 */8)(/* free: ["v1","v2"] *//* free: ["v1"] */v1(/* free: ["v2"] *//* free: ["v2"] *//* 0 */sub(/* free: ["v2"] */v2)(/* 0 */1))))(/* free: ["v3"] */v3); })(/* free: ["v2"] *//* free: ["v2"] *//* 0 */eq(/* free: ["v2"] */v2)(/* 0 */0)); }; })(/* 0 */3))))(/* 0 *//* 0 *//* 0 *//* 0 */maybe(/* 0 */4)(/* 0 */function (v1) { return /* free: ["v1"] *//* free: ["v1"] *//* 0 */mul(/* free: ["v1"] */v1)(/* 0 */8); })(/* 0 *//* 0 */just(/* 0 *//* 0 *//* 0 */sub(/* 0 */3)(/* 0 */2))))

0 comments on commit 42cc1b1

Please sign in to comment.