diff options
author | Eduardo Julian | 2016-12-17 15:28:36 -0400 |
---|---|---|
committer | Eduardo Julian | 2016-12-17 15:28:36 -0400 |
commit | a60af2d673ef6b3c7090e454a1edc59838f3540d (patch) | |
tree | b30b2893426a606e93c7bca1ca5e91a3f2012c68 /stdlib/source | |
parent | e0c21be8ded9924bb0fde7ae5b7bd422d77a6b03 (diff) |
- Added tests for lux/macro/poly/*
Diffstat (limited to 'stdlib/source')
-rw-r--r-- | stdlib/source/lux/compiler.lux | 4 | ||||
-rw-r--r-- | stdlib/source/lux/data/format/json.lux | 51 | ||||
-rw-r--r-- | stdlib/source/lux/macro/poly.lux | 93 | ||||
-rw-r--r-- | stdlib/source/lux/macro/poly/eq.lux | 24 | ||||
-rw-r--r-- | stdlib/source/lux/macro/poly/functor.lux | 52 | ||||
-rw-r--r-- | stdlib/source/lux/macro/poly/text-encoder.lux | 85 |
6 files changed, 198 insertions, 111 deletions
diff --git a/stdlib/source/lux/compiler.lux b/stdlib/source/lux/compiler.lux index fd438b1a3..437389717 100644 --- a/stdlib/source/lux/compiler.lux +++ b/stdlib/source/lux/compiler.lux @@ -98,8 +98,8 @@ (#;Right [compiler' output]) (#;Right [compiler' output])))) -(def: #export (assert test message) - (-> Bool Text (Lux Unit)) +(def: #export (assert message test) + (-> Text Bool (Lux Unit)) (lambda [compiler] (if test (#;Right [compiler []]) diff --git a/stdlib/source/lux/data/format/json.lux b/stdlib/source/lux/data/format/json.lux index e8189a594..1b2c65f97 100644 --- a/stdlib/source/lux/data/format/json.lux +++ b/stdlib/source/lux/data/format/json.lux @@ -744,7 +744,10 @@ _ (compiler;fail "")) - #let [new-*env* (poly;extend-env g!type-fun g!vars *env*)] + #let [new-*env* (poly;extend-env [:x: g!type-fun] + (list;zip2 (|> g!vars list;size poly;type-var-indices) + g!vars) + *env*)] .val. (Codec<JSON,?>//encode new-*env* :val:) #let [:x:+ (case g!vars #;Nil @@ -777,8 +780,10 @@ (|>. (_map_ (~ .sub.)) vector;from-list ;;gen-array))))) (with-gensyms [g!type-fun g!case g!input] (do @ - [[g!vars cases] (poly;variant :x:) - #let [new-*env* (poly;extend-env g!type-fun g!vars *env*)] + [[g!vars members] (poly;variant :x:) + #let [new-*env* (poly;extend-env [:x: g!type-fun] + (list;zip2 (|> g!vars list;size poly;type-var-indices) g!vars) + *env*)] pattern-matching (mapM @ (lambda [[name :case:]] (do @ @@ -787,7 +792,7 @@ (wrap (list (` ((~ tag) (~ g!case))) (` (;;json [(~ (ast;text (product;right name))) ((~ encoder) (~ g!case))])))))) - cases) + members) #let [:x:+ (case g!vars #;Nil (->Codec//encode (type;to-ast :x:)) @@ -803,15 +808,17 @@ ))))) (with-gensyms [g!type-fun g!case g!input] (do @ - [[g!vars slots] (poly;record :x:) - #let [new-*env* (poly;extend-env g!type-fun g!vars *env*)] + [[g!vars members] (poly;record :x:) + #let [new-*env* (poly;extend-env [:x: g!type-fun] + (list;zip2 (|> g!vars list;size poly;type-var-indices) g!vars) + *env*)] synthesis (mapM @ (lambda [[name :slot:]] (do @ [encoder (Codec<JSON,?>//encode new-*env* :slot:)] (wrap [(` (~ (ast;text (product;right name)))) (` ((~ encoder) (get@ (~ (ast;tag name)) (~ g!input))))]))) - slots) + members) #let [:x:+ (case g!vars #;Nil (->Codec//encode (type;to-ast :x:)) @@ -827,7 +834,9 @@ (with-gensyms [g!type-fun g!case] (do @ [[g!vars members] (poly;tuple :x:) - #let [new-*env* (poly;extend-env g!type-fun g!vars *env*)] + #let [new-*env* (poly;extend-env [:x: g!type-fun] + (list;zip2 (|> g!vars list;size poly;type-var-indices) g!vars) + *env*)] pattern-matching (mapM @ (lambda [:member:] (do @ @@ -895,7 +904,9 @@ _ (compiler;fail "")) - #let [new-*env* (poly;extend-env g!type-fun g!vars *env*)] + #let [new-*env* (poly;extend-env [:x: g!type-fun] + (list;zip2 (|> g!vars list;size poly;type-var-indices) g!vars) + *env*)] .val. (Codec<JSON,?>//decode new-*env* :val:) #let [:x:+ (case g!vars #;Nil @@ -921,8 +932,10 @@ <complex> (with-gensyms [g!type-fun g!_] (do @ - [[g!vars cases] (poly;variant :x:) - #let [new-*env* (poly;extend-env g!type-fun g!vars *env*)] + [[g!vars members] (poly;variant :x:) + #let [new-*env* (poly;extend-env [:x: g!type-fun] + (list;zip2 (|> g!vars list;size poly;type-var-indices) g!vars) + *env*)] pattern-matching (mapM @ (lambda [[name :case:]] (do @ @@ -932,7 +945,7 @@ [(~ g!_) (;;at +0 (;;text! (~ (ast;text (product;right name))))) (~ g!_) (;;at +1 (~ decoder))] ((~ (' wrap)) ((~ tag) (~ g!_))))))))) - cases) + members) #let [:x:+ (case g!vars #;Nil (->Codec//decode (type;to-ast :x:)) @@ -953,8 +966,10 @@ )) (with-gensyms [g!type-fun g!case g!input] (do @ - [[g!vars slots] (poly;record :x:) - #let [new-*env* (poly;extend-env g!type-fun g!vars *env*)] + [[g!vars members] (poly;record :x:) + #let [new-*env* (poly;extend-env [:x: g!type-fun] + (list;zip2 (|> g!vars list;size poly;type-var-indices) g!vars) + *env*)] extraction (mapM @ (lambda [[name :slot:]] (do @ @@ -964,7 +979,7 @@ (` (;;get (~ (ast;text (product;right name))) (~ g!input))) g!member (` ((~ decoder) (~ g!member))))))) - slots) + members) #let [:x:+ (case g!vars #;Nil (->Codec//decode (type;to-ast :x:)) @@ -979,12 +994,14 @@ [(~@ (List/join extraction))] ((~ (' wrap)) (~ (ast;record (List/map (lambda [[name :slot:]] [(ast;tag name) (ast;symbol ["" (product;right name)])]) - slots)))))) + members)))))) ))))) (with-gensyms [g!type-fun g!case g!input] (do @ [[g!vars members] (poly;tuple :x:) - #let [new-*env* (poly;extend-env g!type-fun g!vars *env*)] + #let [new-*env* (poly;extend-env [:x: g!type-fun] + (list;zip2 (|> g!vars list;size poly;type-var-indices) g!vars) + *env*)] pattern-matching (mapM @ (lambda [:member:] (do @ diff --git a/stdlib/source/lux/macro/poly.lux b/stdlib/source/lux/macro/poly.lux index 0cf0e64f1..ea2d722ae 100644 --- a/stdlib/source/lux/macro/poly.lux +++ b/stdlib/source/lux/macro/poly.lux @@ -27,7 +27,7 @@ (type: #export (Matcher a) (-> Type (Lux a))) -(type: #export Env (Dict Nat AST)) +(type: #export Env (Dict Nat [Type AST])) ## [Combinators] (do-template [<combinator> <name> <type>] @@ -73,6 +73,8 @@ [_ (<parser> :type:)] (wrap <type>))] + [void Void] + [unit Unit] [bool Bool] [nat Nat] [int Int] @@ -160,7 +162,8 @@ (lambda [:type:] (do compiler;Monad<Lux> [[tags :type:] (tagged :type:) - _ (compiler;assert (n.> +0 (list;size tags)) "Records and variants must have tags.") + _ (compiler;assert "Records and variants must have tags." + (n.> +0 (list;size tags))) [vars :type:] (polymorphic :type:) members (<sub-comb> :type:) #let [num-tags (list;size tags) @@ -239,8 +242,8 @@ (case :type: (#;BoundT idx) (case (dict;get (adjusted-idx env idx) env) - (#;Some poly-val) - (:: compiler;Monad<Lux> wrap poly-val) + (#;Some [poly-type poly-ast]) + (:: compiler;Monad<Lux> wrap poly-ast) #;None (compiler;fail (format "Unknown bound type: " (%type :type:)))) @@ -266,7 +269,7 @@ _ #;None)) t-args)] - (wrap (` ((~ =func) (~@ =args))))) + (wrap (` ((~ (product;right =func)) (~@ (List/map product;right =args)))))) (#;Some call)]) (wrap call) @@ -274,19 +277,32 @@ (compiler;fail (format "Type is not a recursive instance: " (%type :type:)))) ))) +(def: #export (var env var-id) + (-> Env Nat (Matcher Unit)) + (lambda [:type:] + (case :type: + (^=> (#;BoundT idx) + (exec (log! (format "poly;var " (%n idx) " => " (%n (adjusted-idx env idx)))) + (n.= var-id (adjusted-idx env idx)))) + (:: compiler;Monad<Lux> wrap []) + + _ + (compiler;fail (format "Not a bound type: " (%type :type:)))))) + ## [Syntax] -(def: #export (extend-env type-func type-vars env) - (-> AST (List AST) Env Env) +(def: #export (extend-env [funcT funcA] type-vars env) + (-> [Type AST] (List [Type AST]) Env Env) (case type-vars #;Nil env - (#;Cons tvar type-vars') + (#;Cons [varT varA] type-vars') (let [current-size (dict;size env)] (|> env - (dict;put current-size type-func) - (dict;put (n.inc current-size) tvar) - (extend-env (` (#;AppT (~ type-func) (~ tvar))) type-vars') + (dict;put current-size [funcT funcA]) + (dict;put (n.inc current-size) [varT varA]) + (extend-env [(#;AppT funcT varT) (` (#;AppT (~ funcA) (~ varA)))] + type-vars') )))) (syntax: #export (poly: [_ex-lev common;export-level] @@ -351,35 +367,54 @@ (~ impl))))))) ## [Derivers] -(def: #export (contains-bound-types? type) - (-> Type Bool) +(def: (to-ast env type) + (-> Env Type AST) (case type (#;HostT name params) - (list;any? contains-bound-types? params) + (` (#;HostT (~ (ast;text name)) + (list (~@ (List/map (to-ast env) params))))) (^template [<tag>] - (<tag> _) - false) - ([#;VoidT] [#;UnitT] - [#;VarT] [#;ExT] - [#;UnivQ] [#;ExQ]) + <tag> + (` <tag>)) + ([#;VoidT] [#;UnitT]) + + (^template [<tag>] + (<tag> idx) + (` (<tag> (~ (ast;nat idx))))) + ([#;VarT] [#;ExT]) (#;BoundT idx) - true + (let [idx (adjusted-idx env idx)] + (if (n.= +0 idx) + (|> (dict;get idx env) (default (undefined)) product;left (to-ast env)) + (` (;$ (~ (ast;nat (n.dec idx))))))) (^template [<tag>] (<tag> left right) - (or (contains-bound-types? left) - (contains-bound-types? right))) - ([#;LambdaT] [#;AppT] [#;SumT] [#;ProdT]) + (` (<tag> (~ (to-ast env left)) + (~ (to-ast env right))))) + ([#;LambdaT] [#;AppT]) + + (^template [<tag> <macro> <flattener>] + (<tag> left right) + (` (<macro> (~@ (List/map (to-ast env) (<flattener> type)))))) + ([#;SumT | type;flatten-variant] + [#;ProdT & type;flatten-tuple]) (#;NamedT name sub-type) - (contains-bound-types? sub-type) + (ast;symbol name) + + (^template [<tag>] + (<tag> scope body) + (` (<tag> (list (~@ (List/map (to-ast env) scope))) + (~ (to-ast env body))))) + ([#;UnivQ] [#;ExQ]) )) -(def: #export (gen-type converter type-fun tvars type) - (-> (-> AST AST) AST (List AST) Type AST) - (let [type' (type;to-ast type)] +(def: #export (gen-type env converter type-fun tvars type) + (-> Env (-> AST AST) AST (List AST) Type AST) + (let [type' (to-ast env type)] (case tvars #;Nil (converter type') @@ -388,3 +423,7 @@ (` (All (~ type-fun) [(~@ tvars)] (-> (~@ (List/map converter tvars)) (~ (converter (` ((~ type') (~@ tvars))))))))))) + +(def: #export (type-var-indices num-vars) + (-> Nat (List Type)) + (|> num-vars list;indices (List/map (|>. #;BoundT)))) diff --git a/stdlib/source/lux/macro/poly/eq.lux b/stdlib/source/lux/macro/poly/eq.lux index ce42c2eab..dc37e0c9f 100644 --- a/stdlib/source/lux/macro/poly/eq.lux +++ b/stdlib/source/lux/macro/poly/eq.lux @@ -60,8 +60,10 @@ ## Variants (with-gensyms [g!type-fun g!left g!right] (do @ - [[g!vars cases] (poly;variant :x:) - #let [new-env (poly;extend-env g!type-fun g!vars env)] + [[g!vars members] (poly;variant :x:) + #let [new-env (poly;extend-env [:x: g!type-fun] + (list;zip2 (|> g!vars list;size poly;type-var-indices) g!vars) + env)] pattern-matching (mapM @ (lambda [[name :case:]] (do @ @@ -69,20 +71,20 @@ (wrap (list (` [((~ (ast;tag name)) (~ g!left)) ((~ (ast;tag name)) (~ g!right))]) (` ((~ g!eq) (~ g!left) (~ g!right))))))) - cases) + members) #let [base (function$ g!type-fun g!vars (` (lambda [(~ g!left) (~ g!right)] (case [(~ g!left) (~ g!right)] (~@ (List/join pattern-matching))))))]] - (wrap (if (and false (poly;contains-bound-types? :x:)) - base - (` (: (~ (poly;gen-type ->Eq g!type-fun g!vars :x:)) - (~ base))))))) + (wrap (` (: (~ (poly;gen-type new-env ->Eq g!type-fun g!vars :x:)) + (~ base)))))) ## Tuples (with-gensyms [g!type-fun] (do @ [[g!vars members] (poly;tuple :x:) - #let [new-env (poly;extend-env g!type-fun g!vars env)] + #let [new-env (poly;extend-env [:x: g!type-fun] + (list;zip2 (|> g!vars list;size poly;type-var-indices) g!vars) + env)] pattern-matching (mapM @ (lambda [:member:] (do @ @@ -98,10 +100,8 @@ (and (~@ (List/map (lambda [[g!left g!right g!eq]] (` ((~ g!eq) (~ g!left) (~ g!right)))) pattern-matching))))))]] - (wrap (if (and false (poly;contains-bound-types? :x:)) - base - (` (: (~ (poly;gen-type ->Eq g!type-fun g!vars :x:)) - (~ base))))))) + (wrap (` (: (~ (poly;gen-type new-env ->Eq g!type-fun g!vars :x:)) + (~ base)))))) ## Type recursion (poly;recur env :x:) ## Type applications diff --git a/stdlib/source/lux/macro/poly/functor.lux b/stdlib/source/lux/macro/poly/functor.lux index 17fd7808f..e659bb41d 100644 --- a/stdlib/source/lux/macro/poly/functor.lux +++ b/stdlib/source/lux/macro/poly/functor.lux @@ -27,19 +27,25 @@ )) ## [Derivers] -(poly: #export (|Functor| env :x:) +(poly: #export (Functor<?> env :x:) (with-gensyms [g!type-fun g!func g!input] (do @ [#let [g!map (' map)] [g!vars _] (poly;polymorphic :x:) #let [num-vars (list;size g!vars) - new-env (poly;extend-env g!type-fun g!vars env)] - _ (compiler;assert (n.> +0 num-vars) - "Functors must have at least 1 type-variable.")] + new-env (poly;extend-env [:x: g!type-fun] + (list;zip2 (|> g!vars list;size poly;type-var-indices) g!vars) + env)] + _ (compiler;assert "Functors must have at least 1 type-variable." + (n.> +0 num-vars))] (let [->Functor (: (-> AST AST) - (lambda [.type.] (` (functor;Functor (~ .type.))))) - |elem| (: (-> AST (poly;Matcher AST)) - (lambda |elem| [value :type:] + (lambda [.type.] + (if (n.= +1 num-vars) + (` (functor;Functor (~ .type.))) + (let [type-params (|> num-vars n.dec list;indices (List/map (|>. %n ast;local-symbol)))] + (` (All [(~@ type-params)] (functor;Functor ((~ .type.) (~@ type-params))))))))) + Arg<?> (: (-> AST (poly;Matcher AST)) + (lambda Arg<?> [value :type:] ($_ compiler;either ## Nothing to do. (do @ @@ -47,19 +53,23 @@ (wrap value)) ## Type-var (do @ - [_ (poly;var new-env (n.dec num-vars) :type:)] + [_ (poly;var new-env (|> num-vars (n.* +2) n.dec) :type:)] (wrap (` ((~ g!func) (~ value))))) + ## Bound type-variables + (do @ + [_ (poly;bound new-env :type:)] + (wrap value)) ## Tuples/records (do @ - [[g!vars members] (poly;tuple :x:) + [[g!vars members] (poly;tuple :type:) pm (mapM @ (lambda [:slot:] (do @ [g!slot (compiler;gensym "g!slot") - body (|elem| g!slot :slot:)] + body (Arg<?> g!slot :slot:)] (wrap [g!slot body]))) members)] - (wrap (` (case (~ g!input) + (wrap (` (case (~ value) [(~@ (List/map product;left pm))] [(~@ (List/map product;right pm))]) ))) @@ -76,9 +86,9 @@ (lambda [[name :case:]] (do @ [#let [analysis (` ((~ (ast;tag name)) (~ g!input)))] - synthesis (|elem| g!input :case:)] + synthesis (Arg<?> g!input :case:)] (wrap (list analysis - synthesis)))) + (` ((~ (ast;tag name)) (~ synthesis))))))) cases)] (wrap (` (: (~ (->Functor (type;to-ast :x:))) (struct (def: ((~ g!map) (~ g!func) (~ g!input)) @@ -92,7 +102,7 @@ (lambda [:slot:] (do @ [g!slot (compiler;gensym "g!slot") - body (|elem| g!slot :slot:)] + body (Arg<?> g!slot :slot:)] (wrap [g!slot body]))) members)] (wrap (` (: (~ (->Functor (type;to-ast :x:))) @@ -105,18 +115,18 @@ (with-gensyms [g!out] (do @ [[g!vars [:ins: :out:]] (poly;function :x:) - .out. (|elem| g!out :out:) - g!ins (seqM @ - (list;repeat (list;size :ins:) - (compiler;gensym "g!arg")))] + .out. (Arg<?> g!out :out:) + g!envs (seqM @ + (list;repeat (list;size :ins:) + (compiler;gensym "g!envs")))] (wrap (` (: (~ (->Functor (type;to-ast :x:))) (struct (def: ((~ g!map) (~ g!func) (~ g!input)) - (lambda [(~@ g!ins)] - (let [(~ g!out) ((~ g!input) (~@ g!ins))] + (lambda [(~@ g!envs)] + (let [(~ g!out) ((~ g!input) (~@ g!envs))] (~ .out.)))))))))) ## No structure (as you'd expect from Identity) (do @ - [_ (poly;var new-env (n.dec num-vars) :x:)] + [_ (poly;var new-env num-vars :x:)] (wrap (` (: (~ (->Functor (type;to-ast :x:))) (struct (def: ((~ g!map) (~ g!func) (~ g!input)) ((~ g!func) (~ g!input)))))))) diff --git a/stdlib/source/lux/macro/poly/text-encoder.lux b/stdlib/source/lux/macro/poly/text-encoder.lux index c2ab30d7f..858abc208 100644 --- a/stdlib/source/lux/macro/poly/text-encoder.lux +++ b/stdlib/source/lux/macro/poly/text-encoder.lux @@ -26,14 +26,25 @@ [type] )) +(def: (function$ func inputs output) + (-> AST (List AST) AST AST) + (case inputs + #;Nil + output + + _ + (` (lambda (~@ (if (list;empty? inputs) (list) (list func))) + [(~@ inputs)] + (~ output))))) + ## [Derivers] -(poly: #export (|Codec@Text//encode| env :x:) - (let [->Codec//encode (: (-> AST AST) +(poly: #export (Codec<Text,?>::encode env :x:) + (let [->Codec::encode (: (-> AST AST) (lambda [.type.] (` (-> (~ .type.) Text))))] (let% [<basic> (do-template [<type> <matcher> <encoder>] [(do @ [_ (<matcher> :x:)] - (wrap (` (: (~ (->Codec//encode (` <type>))) + (wrap (` (: (~ (->Codec::encode (` <type>))) (~' <encoder>)))))] [Unit poly;unit (lambda [_0] "[]")] @@ -51,73 +62,83 @@ (with-gensyms [g!type-fun g!case g!input] (do @ [[g!vars cases] (poly;variant :x:) - #let [new-env (poly;extend-env g!type-fun g!vars env)] + #let [new-env (poly;extend-env [:x: g!type-fun] + (list;zip2 (|> g!vars list;size poly;type-var-indices) g!vars) + env)] pattern-matching (mapM @ (lambda [[name :case:]] (do @ - [encoder (|Codec@Text//encode| new-env :case:)] + [encoder (Codec<Text,?>::encode new-env :case:)] (wrap (list (` ((~ (ast;tag name)) (~ g!case))) (` (format "(#" (~ (ast;text (Ident/encode name))) " " ((~ encoder) (~ g!case)) ")")))))) - cases)] - (wrap (` (: (~ (poly;gen-type ->Codec//encode g!type-fun g!vars :x:)) - (lambda [(~@ g!vars)] - (lambda [(~ g!input)] - (case (~ g!input) - (~@ (List/join pattern-matching))))) + cases) + #let [base (function$ g!type-fun g!vars + (` (lambda [(~ g!input)] + (case (~ g!input) + (~@ (List/join pattern-matching))))))]] + (wrap (` (: (~ (poly;gen-type env ->Codec::encode g!type-fun g!vars :x:)) + (~ base) ))))) ## Records (with-gensyms [g!type-fun g!case g!input] (do @ [[g!vars slots] (poly;record :x:) - #let [new-env (poly;extend-env g!type-fun g!vars env)] + #let [new-env (poly;extend-env [:x: g!type-fun] + (list;zip2 (|> g!vars list;size poly;type-var-indices) g!vars) + env)] synthesis (mapM @ (lambda [[name :slot:]] (do @ - [encoder (|Codec@Text//encode| new-env :slot:)] + [encoder (Codec<Text,?>::encode new-env :slot:)] (wrap (` (format "#" (~ (ast;text (Ident/encode name))) " " ((~ encoder) (get@ (~ (ast;tag name)) (~ g!input)))))))) - slots)] - (wrap (` (: (~ (poly;gen-type ->Codec//encode g!type-fun g!vars :x:)) - (lambda [(~@ g!vars)] - (lambda [(~ g!input)] - (format "{" (~@ (list;interpose (' " ") synthesis)) "}"))) + slots) + #let [base (function$ g!type-fun g!vars + (` (lambda [(~ g!input)] + (format "{" (~@ (list;interpose (' " ") synthesis)) "}"))))]] + (wrap (` (: (~ (poly;gen-type env ->Codec::encode g!type-fun g!vars :x:)) + (~ base) ))))) ## Tuples (with-gensyms [g!type-fun g!case g!input] (do @ [[g!vars members] (poly;tuple :x:) - #let [new-env (poly;extend-env g!type-fun g!vars env)] + #let [new-env (poly;extend-env [:x: g!type-fun] + (list;zip2 (|> g!vars list;size poly;type-var-indices) g!vars) + env)] parts (mapM @ (lambda [:member:] (do @ [g!member (compiler;gensym "g!member") - encoder (|Codec@Text//encode| new-env :member:)] + encoder (Codec<Text,?>::encode new-env :member:)] (wrap [g!member encoder]))) members) #let [analysis (` [(~@ (List/map product;left parts))]) synthesis (List/map (lambda [[g!member g!encoder]] (` ((~ g!encoder) (~ g!member)))) - parts)]] - (wrap (` (: (~ (poly;gen-type ->Codec//encode g!type-fun g!vars :x:)) - (lambda [(~@ g!vars)] - (lambda [(~ g!input)] - (case (~ g!input) - (~ analysis) - (format "[" (~@ (list;interpose (' " ") synthesis)) "]")))) - ))) - )) + parts) + base (function$ g!type-fun g!vars + (` (lambda [(~ g!input)] + (case (~ g!input) + (~ analysis) + (format "[" (~@ (list;interpose (' " ") synthesis)) "]")))))]] + (wrap (` (: (~ (poly;gen-type env ->Codec::encode g!type-fun g!vars :x:)) + (~ base) + ))))) + ## Type recursion + (poly;recur env :x:) ## Type applications (do @ [[:func: :args:] (poly;apply :x:) - .func. (|Codec@Text//encode| env :func:) - .args. (mapM @ (|Codec@Text//encode| env) :args:)] - (wrap (` (: (~ (->Codec//encode (type;to-ast :x:))) + .func. (Codec<Text,?>::encode env :func:) + .args. (mapM @ (Codec<Text,?>::encode env) :args:)] + (wrap (` (: (~ (->Codec::encode (type;to-ast :x:))) ((~ .func.) (~@ .args.)))))) ## Bound type-variables (poly;bound env :x:) |