git.iko.soy/rowtype-yoga/purescript-yoga-om-layer
on 8a57b3c help sign in
9 files changed+661−323
since splitsnapshots
unifiedsplit
.psc-ide-port+1−1 .spec-results+33−96 README.md−1 compile-fail-tests/RunLayerOpenRowMissingDep.purs−19 spago.lock+613−15 spago.yaml+11−6 src/Yoga/Om/Layer.purs+3−70 test/Test/Yoga/Om/Layer/InstancesSpec.purs−93 test/Test/Yoga/Om/Layer/PureInferenceSpec.purs−22
.psc-ide-port+1−1
@@ -1 +1 @@
1−15500
1+15887
.spec-results+33−96
@@ -1,295 +1,232 @@
11[
2− [
3− "Alt falls back to second layer on failure",
4− {
5− "timestamp": "1775221839085.0",
6− "success": true
7− }
8− ],
92 [
103 "Automatic Memoization builds the same layer only once when used in two branches",
114 {
12− "timestamp": "1775221839085.0",
5+ "timestamp": "1771460758484.0",
136 "success": true
147 }
158 ],
169 [
1710 "Automatic Memoization memoized bracketLayer acquires and releases only once",
1811 {
19− "timestamp": "1775221839085.0",
12+ "timestamp": "1771460758484.0",
2013 "success": true
2114 }
2215 ],
2316 [
2417 "Automatic Memoization memoized scoped layer runs finalizer only once",
2518 {
26− "timestamp": "1775221839085.0",
19+ "timestamp": "1771460758484.0",
2720 "success": true
2821 }
2922 ],
3023 [
3124 "Composition proves Row.Nub deduplicates shared requirements at type level",
3225 {
33− "timestamp": "1775221839085.0",
26+ "timestamp": "1771460758484.0",
3427 "success": true
3528 }
3629 ],
3730 [
3831 "Composition proves deduplication at runtime via shared Ref",
3932 {
40− "timestamp": "1775221839085.0",
33+ "timestamp": "1771460758484.0",
4134 "success": true
4235 }
4336 ],
4437 [
4538 "Error Channel composes layers with different error types",
4639 {
47− "timestamp": "1775221839085.0",
40+ "timestamp": "1771460758484.0",
4841 "success": true
4942 }
5043 ],
5144 [
5245 "Error Channel propagates errors from the first layer",
5346 {
54− "timestamp": "1775221839085.0",
47+ "timestamp": "1771460758484.0",
5548 "success": true
5649 }
5750 ],
5851 [
5952 "Error Channel propagates errors from the second layer",
6053 {
61− "timestamp": "1775221839085.0",
54+ "timestamp": "1771460758484.0",
6255 "success": true
6356 }
6457 ],
6558 [
6659 "Error Channel propagates errors through vertical composition",
6760 {
68− "timestamp": "1775221839085.0",
61+ "timestamp": "1771460758484.0",
6962 "success": true
7063 }
7164 ],
7265 [
7366 "Error Channel scoped layer error triggers finalizers",
7467 {
75− "timestamp": "1775221839085.0",
68+ "timestamp": "1771460758484.0",
7669 "success": true
7770 }
7871 ],
7972 [
8073 "Error Channel scoped layers with errors run via runScopedWith",
8174 {
82− "timestamp": "1775221839085.0",
75+ "timestamp": "1771460758484.0",
8376 "success": true
8477 }
8578 ],
8679 [
8780 "Functor / Apply / Bind applies two layers",
8881 {
89− "timestamp": "1775221839085.0",
82+ "timestamp": "1771460758484.0",
9083 "success": true
9184 }
9285 ],
9386 [
9487 "Functor / Apply / Bind binds layers sequentially",
9588 {
96− "timestamp": "1775221839085.0",
89+ "timestamp": "1771460758484.0",
9790 "success": true
9891 }
9992 ],
10093 [
10194 "Functor / Apply / Bind maps over layer output",
10295 {
103− "timestamp": "1775221839085.0",
104− "success": true
105− }
106− ],
107− [
108− "Functor / Apply / Bind runs layers against a superset context",
109− {
110− "timestamp": "1775221839085.0",
96+ "timestamp": "1771460758484.0",
11197 "success": true
11298 }
11399 ],
114100 [
115101 "Layer recovering does not retry on non-matching errors",
116102 {
117− "timestamp": "1775221839085.0",
103+ "timestamp": "1771460758484.0",
118104 "success": true
119105 }
120106 ],
121107 [
122108 "Layer recovering only retries the specified error in a multi-error layer",
123109 {
124− "timestamp": "1775221839085.0",
110+ "timestamp": "1771460758484.0",
125111 "success": true
126112 }
127113 ],
128114 [
129115 "Layer recovering preserves the error when retries are exhausted",
130116 {
131− "timestamp": "1775221839085.0",
117+ "timestamp": "1771460758484.0",
132118 "success": true
133119 }
134120 ],
135121 [
136122 "Layer recovering retries layer construction on matching errors",
137123 {
138− "timestamp": "1775221839085.0",
124+ "timestamp": "1771460758484.0",
139125 "success": true
140126 }
141127 ],
142128 [
143129 "Layer recovering uses RetryStatus in the check",
144130 {
145− "timestamp": "1775221839085.0",
131+ "timestamp": "1771460758484.0",
146132 "success": true
147133 }
148134 ],
149135 [
150136 "Layer repeating repeats layer construction while condition holds",
151137 {
152− "timestamp": "1775221839085.0",
138+ "timestamp": "1771460758484.0",
153139 "success": true
154140 }
155141 ],
156142 [
157143 "Layer repeating stops when policy exhausted",
158144 {
159− "timestamp": "1775221839085.0",
160− "success": true
161− }
162− ],
163− [
164− "MonadAsk / MonadReader ask reads the context directly",
165− {
166− "timestamp": "1775221839085.0",
167− "success": true
168− }
169− ],
170− [
171− "MonadAsk / MonadReader local modifies context for a layer",
172− {
173− "timestamp": "1775221839085.0",
174− "success": true
175− }
176− ],
177− [
178− "MonadEffect / MonadAff liftEffect works directly in layer bind",
179− {
180− "timestamp": "1775221839085.0",
181− "success": true
182− }
183− ],
184− [
185− "MonadThrow / MonadError throwError raises into the error channel",
186− {
187− "timestamp": "1775221839085.0",
145+ "timestamp": "1771460758484.0",
188146 "success": true
189147 }
190148 ],
191149 [
192150 "Parallel runs layers in parallel via parApply",
193151 {
194− "timestamp": "1775221839085.0",
152+ "timestamp": "1771460758484.0",
195153 "success": true
196154 }
197155 ],
198156 [
199157 "Scoped Layers combines scoped and non-scoped layers",
200158 {
201− "timestamp": "1775221839085.0",
159+ "timestamp": "1771460758484.0",
202160 "success": true
203161 }
204162 ],
205163 [
206164 "Scoped Layers fresh layer builds twice even when same base layer",
207165 {
208− "timestamp": "1775221839085.0",
166+ "timestamp": "1771460758484.0",
209167 "success": true
210168 }
211169 ],
212170 [
213171 "Scoped Layers runs finalizers in reverse order on success",
214172 {
215− "timestamp": "1775221839085.0",
173+ "timestamp": "1771460758484.0",
216174 "success": true
217175 }
218176 ],
219177 [
220178 "Scoped Layers runs finalizers when the callback throws",
221179 {
222− "timestamp": "1775221839085.0",
180+ "timestamp": "1771460758484.0",
223181 "success": true
224182 }
225183 ],
226184 [
227185 "Scoped Layers threads finalizers through vertical composition (provide)",
228186 {
229− "timestamp": "1775221839085.0",
187+ "timestamp": "1771460758484.0",
230188 "success": true
231189 }
232190 ],
233191 [
234192 "Scoped Layers works with bracketLayer",
235193 {
236− "timestamp": "1775221839085.0",
237− "success": true
238− }
239− ],
240− [
241− "Semigroup appends layer outputs",
242− {
243− "timestamp": "1775221839085.0",
244− "success": true
245− }
246− ],
247− [
248− "combinePure combines a plain record with a layer without needing VTA",
249− {
250− "timestamp": "1775214062703.0",
194+ "timestamp": "1771460758484.0",
251195 "success": true
252196 }
253197 ],
254198 [
255199 "wireLayers memoizes shared dependencies within wireLayers",
256200 {
257− "timestamp": "1775221839085.0",
201+ "timestamp": "1771460758484.0",
258202 "success": true
259203 }
260204 ],
261205 [
262206 "wireLayers wireLayersDebug emits dependency graph as compiler warning",
263207 {
264− "timestamp": "1775221839085.0",
208+ "timestamp": "1771460758484.0",
265209 "success": true
266210 }
267211 ],
268212 [
269213 "wireLayers wires a diamond dependency",
270214 {
271− "timestamp": "1775221839085.0",
215+ "timestamp": "1771460758484.0",
272216 "success": true
273217 }
274218 ],
275219 [
276220 "wireLayers wires a simple linear chain (A -> B -> C)",
277221 {
278− "timestamp": "1775221839085.0",
222+ "timestamp": "1771460758484.0",
279223 "success": true
280224 }
281225 ],
282226 [
283227 "wireLayers wires independent layers with no inter-dependencies",
284228 {
285− "timestamp": "1775221839085.0",
286− "success": true
287− }
288− ],
289− [
290− "withValue combines a plain record with a layer without needing VTA",
291− {
292− "timestamp": "1775221839085.0",
229+ "timestamp": "1771460758484.0",
293230 "success": true
294231 }
295232 ]
README.md−1
@@ -240,4 +240,3 @@ combineRequirements (OmLayer build1) (OmLayer build2) = makeLayer do
240240
241241**Status**: Proof of concept complete ✓ with working runtime implementation
242242**Next**: Implement full instance-resolution based layer system with provideLayers API
243−
compile-fail-tests/RunLayerOpenRowMissingDep.pursdeleted−19
@@ -1,19 +0,0 @@
1−-- EXPECT: Prim.RowList.RowToList
2−module Yoga.Om.Layer.CompileFailTest where
3−
4−import Prelude
5−
6−import Yoga.Om as Om
7−import Yoga.Om.Layer (OmLayer, makeLayer, runLayer)
8−
9−type Fastify = String
10−type Connection = String
11−
12−apiLayer :: forall r. OmLayer (fastify :: Fastify, sqlite :: Connection | r) () {}
13−apiLayer = makeLayer do
14− { fastify, sqlite } <- Om.ask
15− let _ = fastify <> sqlite
16− pure {}
17−
18−bad :: Om.Om { fastify :: Fastify } () {}
19−bad = runLayer { fastify: "server" } apiLayer
spago.lock+613−15
@@ -6,7 +6,7 @@
66 "core": {
77 "dependencies": [
88 {
9− "aff": ">=8.0.0 <9.0.0"
9+ "aff": ">=7.0.0 <9.0.0"
1010 },
1111 {
1212 "aff-retry": ">=2.0.0 <3.0.0"
@@ -14,9 +14,6 @@
1414 {
1515 "arrays": ">=7.3.0 <8.0.0"
1616 },
17− {
18− "control": ">=6.0.0 <7.0.0"
19− },
2017 {
2118 "effect": ">=4.0.0 <5.0.0"
2219 },
@@ -48,10 +45,10 @@
4845 "record-studio": ">=1.0.4 <2.0.0"
4946 },
5047 {
51− "refs": ">=6.0.0 <7.0.0"
48+ "ref-lifted": ">=0.0.1 <1.0.0"
5249 },
5350 {
54− "tailrec": ">=6.1.0 <7.0.0"
51+ "refs": ">=6.0.0 <7.0.0"
5552 },
5653 {
5754 "transformers": ">=6.1.0 <7.0.0"
@@ -69,7 +66,7 @@
6966 "variant": ">=8.0.0 <9.0.0"
7067 },
7168 {
72− "yoga-om": ">=2.0.0 <3.0.0"
69+ "yoga-om": ">=1.4.0 <2.0.0"
7370 }
7471 ]
7572 },
@@ -94,7 +91,602 @@
9491 }
9592 }
9693 },
97− "extra_packages": {}
94+ "package_set": {
95+ "address": {
96+ "registry": "73.0.0"
97+ },
98+ "compiler": ">=0.15.15 <0.16.0",
99+ "content": {
100+ "abc-parser": "2.1.0",
101+ "ace": "9.1.0",
102+ "address-rfc2821": "0.1.1",
103+ "aff": "8.0.0",
104+ "aff-bus": "6.0.0",
105+ "aff-coroutines": "9.0.0",
106+ "aff-promise": "4.0.0",
107+ "aff-retry": "2.0.0",
108+ "affjax": "13.0.0",
109+ "affjax-node": "1.0.0",
110+ "affjax-web": "1.0.0",
111+ "ansi": "7.0.0",
112+ "apexcharts": "0.5.0",
113+ "applicative-phases": "1.0.0",
114+ "argonaut": "9.0.0",
115+ "argonaut-aeson-generic": "0.4.1",
116+ "argonaut-codecs": "9.1.0",
117+ "argonaut-core": "7.0.0",
118+ "argonaut-generic": "8.0.0",
119+ "argonaut-traversals": "10.0.0",
120+ "argparse-basic": "2.0.0",
121+ "array-builder": "0.1.2",
122+ "array-search": "0.6.0",
123+ "arraybuffer": "13.2.0",
124+ "arraybuffer-builder": "3.1.0",
125+ "arraybuffer-types": "3.0.2",
126+ "arrays": "7.3.0",
127+ "arrays-extra": "0.6.1",
128+ "arrays-zipper": "2.0.1",
129+ "ask": "1.0.0",
130+ "assert": "6.0.0",
131+ "assert-multiple": "0.4.0",
132+ "avar": "5.0.1",
133+ "axon": "0.0.3",
134+ "b64": "0.0.8",
135+ "barbies": "1.0.1",
136+ "barlow-lens": "0.9.0",
137+ "benchlib": "0.0.4",
138+ "bifunctors": "6.1.0",
139+ "bigints": "7.0.1",
140+ "blessed": "1.0.0",
141+ "bolson": "0.3.9",
142+ "bookhound": "0.1.7",
143+ "bower-json": "3.0.0",
144+ "call-by-name": "4.0.1",
145+ "canvas": "6.0.0",
146+ "canvas-action": "9.0.0",
147+ "cartesian": "1.0.6",
148+ "catenable-lists": "7.0.0",
149+ "cbor-stream": "1.3.0",
150+ "chameleon": "1.0.0",
151+ "chameleon-halogen": "1.0.3",
152+ "chameleon-react-basic": "1.1.0",
153+ "chameleon-styled": "2.5.0",
154+ "chameleon-transformers": "1.0.0",
155+ "channel": "1.0.0",
156+ "checked-exceptions": "3.1.1",
157+ "choku": "1.0.2",
158+ "classless": "0.1.1",
159+ "classless-arbitrary": "0.1.1",
160+ "classless-decode-json": "0.1.1",
161+ "classless-encode-json": "0.1.3",
162+ "classnames": "2.0.0",
163+ "codec": "6.1.0",
164+ "codec-argonaut": "10.0.0",
165+ "codec-json": "2.0.0",
166+ "colors": "7.0.1",
167+ "concur-core": "0.5.0",
168+ "concur-react": "0.5.0",
169+ "concurrent-queues": "3.0.0",
170+ "console": "6.1.0",
171+ "const": "6.0.0",
172+ "contravariant": "6.0.0",
173+ "control": "6.0.0",
174+ "convertable-options": "1.0.0",
175+ "coroutines": "7.0.0",
176+ "css": "6.0.0",
177+ "css-class-name-extractor": "0.0.4",
178+ "css-frameworks": "1.1.0",
179+ "csv-stream": "2.3.0",
180+ "data-mvc": "0.0.2",
181+ "datetime": "6.1.0",
182+ "datetime-parsing": "0.2.0",
183+ "debounce": "0.1.0",
184+ "debug": "6.0.2",
185+ "decimals": "7.1.0",
186+ "default-values": "1.0.1",
187+ "deku": "0.9.23",
188+ "deno": "0.0.5",
189+ "dissect": "1.0.0",
190+ "distributive": "6.0.0",
191+ "dodo-printer": "2.2.3",
192+ "dom-filereader": "7.0.0",
193+ "dom-indexed": "13.0.0",
194+ "dom-simple": "0.4.0",
195+ "dotenv": "4.0.3",
196+ "droplet": "0.6.0",
197+ "dts": "1.0.0",
198+ "dual-numbers": "1.0.3",
199+ "dynamic-buffer": "3.0.1",
200+ "echarts-simple": "0.0.1",
201+ "effect": "4.0.0",
202+ "either": "6.1.0",
203+ "elmish": "0.13.0",
204+ "elmish-enzyme": "0.1.1",
205+ "elmish-hooks": "0.11.0",
206+ "elmish-html": "0.10.0",
207+ "elmish-testing-library": "0.3.2",
208+ "elmish-time-machine": "0.4.2",
209+ "email-validate": "7.0.0",
210+ "encoding": "0.0.9",
211+ "enums": "6.0.1",
212+ "env-names": "0.4.0",
213+ "environment": "2.0.0",
214+ "error": "2.0.0",
215+ "eta-conversion": "0.3.2",
216+ "exceptions": "6.1.0",
217+ "exists": "6.0.0",
218+ "exitcodes": "4.0.0",
219+ "expect-inferred": "3.0.0",
220+ "express": "0.9.1",
221+ "ezfetch": "1.1.1",
222+ "fahrtwind": "2.0.0",
223+ "fakerjs": "0.0.1",
224+ "fallback": "0.1.0",
225+ "fast-vect": "1.2.0",
226+ "fetch": "4.1.0",
227+ "fetch-argonaut": "1.0.1",
228+ "fetch-core": "5.1.0",
229+ "fetch-yoga-json": "1.1.0",
230+ "ffi-simple": "0.5.1",
231+ "fft": "0.3.0",
232+ "fft-js": "0.1.0",
233+ "filterable": "5.0.0",
234+ "fix-functor": "0.1.0",
235+ "fixed-points": "7.0.0",
236+ "fixed-precision": "5.0.0",
237+ "flame": "1.6.0",
238+ "float32": "2.0.0",
239+ "fmt": "0.2.1",
240+ "foldable-traversable": "6.0.0",
241+ "foldable-traversable-extra": "0.0.6",
242+ "foreign": "7.0.0",
243+ "foreign-object": "4.1.0",
244+ "foreign-readwrite": "3.4.0",
245+ "forgetmenot": "0.1.0",
246+ "fork": "6.0.0",
247+ "form-urlencoded": "7.0.0",
248+ "formatters": "7.0.0",
249+ "framer-motion": "2.0.1",
250+ "free": "7.1.0",
251+ "freeap": "7.0.0",
252+ "freer-free": "0.0.1",
253+ "freet": "7.0.0",
254+ "functions": "6.0.0",
255+ "functor1": "3.0.0",
256+ "functors": "5.0.0",
257+ "fuzzy": "0.4.0",
258+ "gen": "4.0.0",
259+ "generate-values": "1.0.1",
260+ "generic-router": "0.0.1",
261+ "geojson": "0.0.5",
262+ "geometria": "2.2.0",
263+ "gesso": "1.0.1",
264+ "gojs": "0.1.1",
265+ "golem-fetch": "0.1.0",
266+ "grain": "3.0.0",
267+ "grain-router": "3.0.0",
268+ "grain-virtualized": "3.0.0",
269+ "graphql-client": "10.1.1",
270+ "graphs": "8.1.0",
271+ "group": "4.1.1",
272+ "halogen": "7.0.0",
273+ "halogen-bootstrap5": "5.3.2",
274+ "halogen-canvas": "1.0.0",
275+ "halogen-css": "10.0.0",
276+ "halogen-declarative-canvas": "0.0.8",
277+ "halogen-echarts-simple": "0.0.4",
278+ "halogen-formless": "4.0.3",
279+ "halogen-helix": "1.1.0",
280+ "halogen-hooks": "0.6.3",
281+ "halogen-hooks-extra": "0.9.0",
282+ "halogen-infinite-scroll": "1.1.0",
283+ "halogen-store": "0.5.4",
284+ "halogen-storybook": "2.0.0",
285+ "halogen-subscriptions": "2.0.0",
286+ "halogen-svg-elems": "8.0.0",
287+ "halogen-typewriter": "1.0.4",
288+ "halogen-use-trigger-hooks": "1.0.0",
289+ "halogen-vdom": "8.0.0",
290+ "halogen-vdom-string-renderer": "0.5.0",
291+ "halogen-xterm": "2.0.0",
292+ "heckin": "2.0.1",
293+ "heterogeneous": "0.7.0",
294+ "homogeneous": "0.4.0",
295+ "http-methods": "6.0.0",
296+ "httpurple": "4.0.0",
297+ "huffman": "0.4.0",
298+ "humdrum": "0.0.1",
299+ "hylograph-canvas": "0.1.0",
300+ "hylograph-d3-kernel": "0.1.0",
301+ "hylograph-graph": "0.1.0",
302+ "hylograph-layout": "0.1.0",
303+ "hylograph-music": "0.1.0",
304+ "hylograph-optics": "0.1.0",
305+ "hylograph-selection": "0.1.1",
306+ "hylograph-simulation": "0.1.0",
307+ "hylograph-simulation-core": "0.1.0",
308+ "hylograph-simulation-halogen": "0.1.0",
309+ "hylograph-transitions": "0.1.0",
310+ "hylograph-wasm-kernel": "0.1.0",
311+ "hyrule": "2.3.8",
312+ "identity": "6.0.0",
313+ "identy": "4.0.1",
314+ "indexed-db": "1.0.0",
315+ "indexed-monad": "3.0.0",
316+ "ink": "0.0.1",
317+ "int64": "3.0.0",
318+ "integers": "6.0.0",
319+ "interpolate": "5.0.2",
320+ "intersection-observer": "1.0.1",
321+ "invariant": "6.0.0",
322+ "jarilo": "1.0.1",
323+ "jelly": "0.10.0",
324+ "jelly-router": "0.3.0",
325+ "jelly-signal": "0.4.0",
326+ "jest": "1.0.0",
327+ "js-abort-controller": "1.0.0",
328+ "js-bigints": "2.2.1",
329+ "js-date": "8.0.0",
330+ "js-fetch": "0.2.1",
331+ "js-fileio": "3.0.0",
332+ "js-intl": "1.1.4",
333+ "js-iterators": "0.1.1",
334+ "js-maps": "0.1.2",
335+ "js-promise": "1.0.0",
336+ "js-promise-aff": "1.0.0",
337+ "js-timers": "6.1.0",
338+ "js-uri": "3.1.0",
339+ "jsdom": "1.0.0",
340+ "json": "1.1.0",
341+ "json-codecs": "5.0.0",
342+ "justifill": "0.5.0",
343+ "jwt": "0.0.9",
344+ "labeled-data": "0.2.0",
345+ "language-cst-parser": "0.14.1",
346+ "lazy": "6.0.0",
347+ "lazy-joe": "1.0.0",
348+ "lcg": "4.0.0",
349+ "leibniz": "5.0.0",
350+ "leveldb": "1.0.1",
351+ "liminal": "1.0.1",
352+ "linalg": "6.0.0",
353+ "lists": "7.0.0",
354+ "literals": "1.0.2",
355+ "logging": "3.0.0",
356+ "logging-journald": "0.4.0",
357+ "lumi-components": "18.0.0",
358+ "machines": "7.0.0",
359+ "maps-eager": "0.5.0",
360+ "marionette": "1.0.0",
361+ "marionette-react-basic-hooks": "0.1.1",
362+ "marked": "0.1.0",
363+ "matrices": "5.0.1",
364+ "matryoshka": "1.0.0",
365+ "maybe": "6.0.0",
366+ "media-types": "6.0.0",
367+ "meowclient": "1.0.0",
368+ "midi": "4.0.0",
369+ "milkis": "9.0.0",
370+ "mimetype": "0.0.1",
371+ "minibench": "4.0.1",
372+ "mmorph": "7.0.0",
373+ "monad-control": "5.0.0",
374+ "monad-logger": "1.3.1",
375+ "monad-loops": "0.5.0",
376+ "monad-unlift": "1.0.1",
377+ "monoid-extras": "0.0.1",
378+ "monoidal": "0.16.0",
379+ "morello": "0.4.0",
380+ "mote": "3.0.0",
381+ "motsunabe": "2.0.0",
382+ "mvc": "0.0.1",
383+ "mysql": "6.0.1",
384+ "n3": "0.1.0",
385+ "nano-id": "1.1.0",
386+ "nanoid": "0.1.0",
387+ "naturals": "3.0.0",
388+ "nested-functor": "0.2.1",
389+ "newtype": "5.0.0",
390+ "nextjs": "0.1.1",
391+ "nextui": "0.2.0",
392+ "node-buffer": "9.0.0",
393+ "node-child-process": "11.1.0",
394+ "node-event-emitter": "3.0.0",
395+ "node-execa": "5.0.0",
396+ "node-fs": "9.2.0",
397+ "node-glob-basic": "2.0.0",
398+ "node-http": "9.1.0",
399+ "node-http2": "1.1.1",
400+ "node-human-signals": "1.0.0",
401+ "node-net": "5.1.0",
402+ "node-os": "5.1.0",
403+ "node-path": "5.0.1",
404+ "node-process": "11.2.0",
405+ "node-readline": "8.1.1",
406+ "node-sqlite3": "8.0.0",
407+ "node-stream-pipes": "2.1.6",
408+ "node-streams": "9.0.1",
409+ "node-tls": "0.3.1",
410+ "node-url": "7.0.1",
411+ "node-workerbees": "0.3.1",
412+ "node-zlib": "0.4.0",
413+ "nonempty": "7.0.0",
414+ "now": "6.0.0",
415+ "npm-package-json": "2.0.0",
416+ "nullable": "6.0.0",
417+ "numberfield": "0.2.2",
418+ "numbers": "9.0.1",
419+ "oak": "3.1.1",
420+ "oak-debug": "1.2.2",
421+ "object-maps": "0.3.0",
422+ "ocarina": "1.5.4",
423+ "oooooooooorrrrrrrmm-lib": "0.0.1",
424+ "open-colors-scales-and-schemes": "1.0.0",
425+ "open-drawing": "6.0.4",
426+ "open-folds": "6.4.0",
427+ "open-foreign-generic": "11.0.3",
428+ "open-memoize": "6.2.0",
429+ "open-mkdirp-aff": "1.2.0",
430+ "open-pairing": "6.2.0",
431+ "open-smolder": "12.0.2",
432+ "options": "7.0.0",
433+ "optparse": "5.0.1",
434+ "ordered-collections": "3.2.0",
435+ "ordered-set": "0.4.0",
436+ "orders": "6.0.0",
437+ "org-doc": "0.1.0",
438+ "owoify": "1.2.0",
439+ "pairs": "9.0.1",
440+ "parallel": "7.0.0",
441+ "parsing": "11.0.0",
442+ "parsing-dataview": "3.2.4",
443+ "partial": "4.0.0",
444+ "pathy": "9.0.0",
445+ "pha": "0.13.0",
446+ "phaser": "0.7.0",
447+ "phylio": "1.1.2",
448+ "pipes": "8.0.0",
449+ "pirates-charm": "0.0.1",
450+ "play": "1.0.0",
451+ "pmock": "0.9.0",
452+ "point-free": "1.0.0",
453+ "pointed-list": "0.5.1",
454+ "polymorphic-vectors": "4.0.0",
455+ "posix-types": "6.0.0",
456+ "postgresql": "2.0.21",
457+ "precise": "6.0.0",
458+ "precise-datetime": "7.0.0",
459+ "prelude": "6.0.2",
460+ "prettier-printer": "3.0.0",
461+ "printf": "0.1.0",
462+ "priority-queue": "0.1.2",
463+ "profunctor": "6.0.1",
464+ "profunctor-lenses": "8.0.0",
465+ "protobuf": "4.4.0",
466+ "psa-utils": "8.0.0",
467+ "psci-support": "6.0.0",
468+ "punycode": "1.0.0",
469+ "pursfmt": "0.17.0",
470+ "qualified-do": "2.2.0",
471+ "quantities": "12.2.0",
472+ "quickcheck": "8.0.1",
473+ "quickcheck-combinators": "0.1.3",
474+ "quickcheck-laws": "7.0.0",
475+ "quickcheck-utf8": "0.0.0",
476+ "random": "6.0.0",
477+ "rationals": "6.0.0",
478+ "rdf": "0.1.0",
479+ "react": "11.0.0",
480+ "react-aria": "0.2.0",
481+ "react-basic": "17.0.0",
482+ "react-basic-classic": "3.0.0",
483+ "react-basic-dnd": "10.1.0",
484+ "react-basic-dom": "7.0.0",
485+ "react-basic-dom-beta": "0.1.1",
486+ "react-basic-emotion": "7.1.0",
487+ "react-basic-hooks": "9.0.0",
488+ "react-basic-storybook": "2.0.0",
489+ "react-dom": "8.0.0",
490+ "react-halo": "3.0.0",
491+ "react-icons": "1.1.5",
492+ "react-markdown": "0.1.0",
493+ "react-testing-library": "4.0.1",
494+ "react-virtuoso": "1.0.0",
495+ "reactix": "0.6.1",
496+ "read": "1.0.1",
497+ "recharts": "1.1.0",
498+ "record": "4.0.0",
499+ "record-extra": "5.0.1",
500+ "record-extra-srghma": "0.2.8",
501+ "record-ptional-fields": "0.1.2",
502+ "record-studio": "1.0.4",
503+ "refs": "6.0.0",
504+ "remotedata": "5.0.1",
505+ "repr": "0.5.0",
506+ "resize-arrays": "0.0.1",
507+ "resize-observer": "1.0.0",
508+ "resource": "2.0.1",
509+ "resourcet": "1.0.0",
510+ "result": "1.0.3",
511+ "return": "0.2.0",
512+ "ring-modules": "5.0.1",
513+ "rito": "0.3.4",
514+ "roman": "0.4.0",
515+ "rough-notation": "1.0.2",
516+ "routing": "11.0.0",
517+ "routing-duplex": "0.7.0",
518+ "run": "5.0.0",
519+ "safe-coerce": "2.0.0",
520+ "safely": "4.0.1",
521+ "school-of-music": "1.3.0",
522+ "selection-foldable": "0.2.0",
523+ "selective-functors": "1.0.1",
524+ "semirings": "7.0.0",
525+ "shuffle": "2.0.0",
526+ "signal": "13.0.0",
527+ "simple-emitter": "3.0.1",
528+ "simple-i18n": "2.0.1",
529+ "simple-json": "9.0.0",
530+ "simple-json-generics": "0.2.1",
531+ "simple-ulid": "3.0.0",
532+ "sized-matrices": "1.0.0",
533+ "sized-vectors": "5.0.2",
534+ "slug": "3.2.0",
535+ "small-ffi": "4.0.1",
536+ "soundfonts": "4.1.0",
537+ "sparse-matrices": "2.0.1",
538+ "sparse-polynomials": "3.0.1",
539+ "spec": "8.1.1",
540+ "spec-discovery": "8.4.0",
541+ "spec-mocha": "5.1.1",
542+ "spec-node": "0.0.3",
543+ "spec-quickcheck": "5.0.2",
544+ "spec-reporter-xunit": "0.7.1",
545+ "splitmix": "2.1.0",
546+ "ssrs": "1.0.0",
547+ "st": "6.2.0",
548+ "statistics": "0.3.2",
549+ "strictlypositiveint": "1.0.1",
550+ "string-parsers": "8.0.0",
551+ "strings": "6.0.1",
552+ "strings-extra": "4.0.0",
553+ "stringutils": "0.0.12",
554+ "structured-logging": "1.0.0",
555+ "substitute": "0.2.3",
556+ "supply": "0.2.0",
557+ "svg-parser": "3.0.0",
558+ "systemd-journald": "0.3.0",
559+ "tagged": "4.0.2",
560+ "tailrec": "6.1.0",
561+ "tanstack-query": "2.0.0",
562+ "tecton": "0.2.1",
563+ "tecton-halogen": "0.2.0",
564+ "test-unit": "17.0.0",
565+ "text-formatting": "0.1.0",
566+ "thermite": "6.3.1",
567+ "thermite-dom": "0.3.1",
568+ "these": "6.0.0",
569+ "threading": "0.0.3",
570+ "tidy": "0.11.1",
571+ "tidy-codegen": "4.0.1",
572+ "tldr": "0.0.0",
573+ "toestand": "0.9.0",
574+ "transformation-matrix": "1.0.1",
575+ "transformers": "6.1.0",
576+ "transit": "1.0.0",
577+ "tree-rose": "4.0.2",
578+ "trivial-unfold": "0.5.0",
579+ "ts-bridge": "4.0.0",
580+ "tuples": "7.0.0",
581+ "two-or-more": "1.0.0",
582+ "type-equality": "4.0.1",
583+ "typedenv": "2.0.1",
584+ "typelevel": "6.0.0",
585+ "typelevel-lists": "2.1.0",
586+ "typelevel-peano": "1.0.1",
587+ "typelevel-prelude": "7.0.0",
588+ "typelevel-regex": "0.0.3",
589+ "typelevel-rows": "0.1.0",
590+ "typisch": "0.4.0",
591+ "uint": "7.0.0",
592+ "ulid": "3.0.1",
593+ "uncurried-transformers": "1.1.0",
594+ "undefined": "2.0.0",
595+ "undefined-is-not-a-problem": "1.1.0",
596+ "unfoldable": "6.0.0",
597+ "unicode": "6.0.0",
598+ "unique": "0.6.1",
599+ "unlift": "1.0.1",
600+ "unordered-collections": "3.1.0",
601+ "unsafe-coerce": "6.0.0",
602+ "unsafe-reference": "5.0.0",
603+ "untagged-to-tagged": "0.1.4",
604+ "untagged-union": "1.0.0",
605+ "uri": "9.0.0",
606+ "url-immutable": "1.0.0",
607+ "url-regex-safe": "0.1.1",
608+ "uuid": "9.0.0",
609+ "uuidv4": "1.0.0",
610+ "validation": "6.0.0",
611+ "variant": "8.0.0",
612+ "variant-encodings": "2.0.0",
613+ "variant-gen": "1.0.0",
614+ "vectorfield": "1.0.1",
615+ "vectors": "2.1.0",
616+ "versions": "7.0.0",
617+ "visx": "0.0.2",
618+ "vitest": "2.0.0",
619+ "web-clipboard": "6.0.0",
620+ "web-cssom": "2.0.0",
621+ "web-cssom-view": "0.1.0",
622+ "web-dom": "6.0.0",
623+ "web-dom-parser": "8.0.0",
624+ "web-dom-xpath": "3.0.0",
625+ "web-encoding": "3.0.0",
626+ "web-events": "4.0.0",
627+ "web-fetch": "4.0.1",
628+ "web-file": "4.0.0",
629+ "web-geometry": "0.1.0",
630+ "web-html": "4.1.1",
631+ "web-pointerevents": "2.0.0",
632+ "web-proletarian": "1.0.0",
633+ "web-promise": "3.2.0",
634+ "web-resize-observer": "2.1.0",
635+ "web-router": "1.0.0",
636+ "web-socket": "4.0.0",
637+ "web-storage": "5.0.0",
638+ "web-streams": "4.0.0",
639+ "web-touchevents": "4.0.0",
640+ "web-uievents": "5.0.0",
641+ "web-url": "2.0.0",
642+ "web-workers": "1.1.0",
643+ "web-xhr": "5.0.1",
644+ "webb-aff-list": "0.0.2",
645+ "webb-array": "0.0.2",
646+ "webb-channel": "0.0.3",
647+ "webb-commandline": "0.0.3",
648+ "webb-directory": "0.0.7",
649+ "webb-file": "0.0.1",
650+ "webb-map": "0.0.1",
651+ "webb-monad": "0.0.2",
652+ "webb-mutex": "0.0.7",
653+ "webb-parsing": "0.0.5",
654+ "webb-random": "0.0.1",
655+ "webb-refer": "0.0.3",
656+ "webb-set": "0.0.1",
657+ "webb-slot": "0.0.1",
658+ "webb-stateful": "0.0.3",
659+ "webb-string": "0.0.1",
660+ "webb-test": "0.0.1",
661+ "webb-thread": "0.0.2",
662+ "webb-writer": "0.0.3",
663+ "webextension-polyfill": "0.1.0",
664+ "webgpu": "0.0.1",
665+ "which": "2.0.0",
666+ "whine-core": "0.0.33",
667+ "xterm": "1.0.0",
668+ "yaml-next": "3.1.1",
669+ "yoga-fetch": "1.0.1",
670+ "yoga-json": "5.1.0",
671+ "yoga-om": "0.1.0",
672+ "yoga-postgres": "6.0.0",
673+ "yoga-react-dom": "1.0.1",
674+ "yoga-redis": "0.1.0",
675+ "yoga-sql-types": "0.1.0",
676+ "yoga-subtlecrypto": "0.1.0",
677+ "yoga-test-docker": "0.1.0",
678+ "yoga-tree": "1.0.0",
679+ "yoga-tree-svg": "0.1.0",
680+ "yoga-tree-utils": "1.0.0",
681+ "z3": "0.0.2",
682+ "zipperarray": "2.0.0"
683+ }
684+ },
685+ "extra_packages": {
686+ "ref-lifted": {
687+ "path": "../purescript-ref-lifted"
688+ }
689+ }
98690 },
99691 "packages": {
100692 "aff": {
@@ -985,6 +1577,15 @@
9851577 "unsafe-coerce"
9861578 ]
9871579 },
1580+ "ref-lifted": {
1581+ "type": "local",
1582+ "path": "../purescript-ref-lifted",
1583+ "dependencies": [
1584+ "effect",
1585+ "prelude",
1586+ "refs"
1587+ ]
1588+ },
9881589 "refs": {
9891590 "type": "registry",
9901591 "version": "6.0.0",
@@ -1004,8 +1605,8 @@
10041605 },
10051606 "spec": {
10061607 "type": "registry",
1007− "version": "8.1.2",
1008− "integrity": "sha256-klPPJ6lBQI1CGOAdLJ+ZoGRt8XZippkTKjn53BrSkL0=",
1608+ "version": "8.1.1",
1609+ "integrity": "sha256-b6qjDb7lUJGLV+WEoywLu6BCXC4zGpfbN43mTL+vBeI=",
10091610 "dependencies": [
10101611 "aff",
10111612 "ansi",
@@ -1231,11 +1832,10 @@
12311832 },
12321833 "yoga-om": {
12331834 "type": "registry",
1234− "version": "2.0.0",
1235− "integrity": "sha256-eenoujD2rJzR6gYJbbIiqLhXHC1C5dagu91HZkAEt/Y=",
1835+ "version": "0.1.0",
1836+ "integrity": "sha256-0EGWo/UOVLzZ14DPtdv0C+bTvNO49wNgtTBIXI6QHqU=",
12361837 "dependencies": [
12371838 "aff",
1238− "aff-retry",
12391839 "avar",
12401840 "console",
12411841 "control",
@@ -1244,14 +1844,12 @@
12441844 "either",
12451845 "exceptions",
12461846 "functions",
1247− "heterogeneous",
12481847 "maybe",
12491848 "newtype",
12501849 "parallel",
12511850 "prelude",
12521851 "record",
12531852 "record-studio",
1254− "refs",
12551853 "tailrec",
12561854 "transformers",
12571855 "tuples",
spago.yaml+11−6
@@ -1,17 +1,22 @@
1−workspace: {}
1+workspace:
2+ packageSet:
3+ registry: 73.0.0
4+ extraPackages:
5+ ref-lifted:
6+ path: ../purescript-ref-lifted
7+
28package:
39 name: yoga-om-layer
410 publish:
5− version: 2.1.0
11+ version: 1.2.0
612 license: MIT
713 location:
814 githubOwner: rowtype-yoga
915 githubRepo: purescript-yoga-om-layer
1016 dependencies:
11− - aff: ">=8.0.0 <9.0.0"
17+ - aff: ">=7.0.0 <9.0.0"
1218 - aff-retry: ">=2.0.0 <3.0.0"
1319 - arrays: ">=7.3.0 <8.0.0"
14− - control: ">=6.0.0 <7.0.0"
1520 - effect: ">=4.0.0 <5.0.0"
1621 - exceptions: ">=6.1.0 <7.0.0"
1722 - foldable-traversable: ">=6.0.0 <7.0.0"
@@ -22,14 +27,14 @@ package:
2227 - prelude: ">=6.0.2 <7.0.0"
2328 - record: ">=4.0.0 <5.0.0"
2429 - record-studio: ">=1.0.4 <2.0.0"
30+ - ref-lifted: ">=0.0.1 <1.0.0"
2531 - refs: ">=6.0.0 <7.0.0"
26− - tailrec: ">=6.1.0 <7.0.0"
2732 - transformers: ">=6.1.0 <7.0.0"
2833 - type-equality: ">=4.0.1 <5.0.0"
2934 - typelevel-prelude: ">=7.0.0 <8.0.0"
3035 - unsafe-coerce: ">=6.0.0 <7.0.0"
3136 - variant: ">=8.0.0 <9.0.0"
32− - yoga-om: ">=2.0.0 <3.0.0"
37+ - yoga-om: ">=1.4.0 <2.0.0"
3338 test:
3439 main: Test.Main
3540 dependencies:
src/Yoga/Om/Layer.purs+3−70
@@ -15,7 +15,6 @@ module Yoga.Om.Layer
1515 , withScopedWith
1616 , scoped
1717 , combineRequirements
18− , withValue
1918 , provide
2019 , (>->)
2120 , recovering
@@ -53,19 +52,10 @@ module Yoga.Om.Layer
5352
5453import Prelude
5554
56−import Control.Alt (class Alt)
57−import Control.Alt as Alt
58−import Control.Alternative (class Alternative)
59−import Control.Monad.Error.Class (class MonadError, class MonadThrow, catchError, throwError)
60−import Control.Monad.Reader (class MonadAsk, class MonadReader)
61−import Control.Monad.Reader as Reader
62−import Control.Monad.Rec.Class (class MonadRec, Step(..), tailRecM)
55+import Control.Monad.Error.Class (catchError, throwError)
56+import Data.Symbol (class IsSymbol)
6357import Control.Parallel (class Parallel)
6458import Control.Parallel as Parallel
65−import Control.Plus (class Plus)
66−import Control.Plus as Plus
67−import Data.Symbol (class IsSymbol)
68−import Data.Variant (Variant)
6959import Data.Array as Array
7060import Data.Foldable (for_)
7161import Data.Map (Map)
@@ -76,10 +66,7 @@ import Data.Variant (class VariantMatchCases, onMatch)
7666import Effect (Effect)
7767import Effect.Aff (Aff, bracket)
7868import Effect.Aff.Retry (RetryPolicyM, RetryStatus, applyAndDelay, defaultRetryStatus)
79−import Effect.Aff.Class (class MonadAff)
80−import Effect.Aff.Class as Aff
81−import Effect.Class (class MonadEffect, liftEffect)
82−import Effect.Class (class MonadEffect, liftEffect) as Effect
69+import Effect.Class (liftEffect)
8370import Effect.Exception (Error)
8471import Effect.Ref (Ref)
8572import Effect.Ref as Ref
@@ -99,7 +86,6 @@ import Type.Equality (class TypeEquals)
9986import Unsafe.Coerce (unsafeCoerce)
10087import Yoga.Om (Om, ParOm)
10188import Yoga.Om as Om
102−import Yoga.Om.Error (Exception)
10389
10490-- =============================================================================
10591-- Scope — a first-class representation of resource lifetime
@@ -188,36 +174,6 @@ instance Bind (OmLayer req err) where
188174
189175instance Monad (OmLayer req err)
190176
191−instance MonadEffect (OmLayer req err) where
192− liftEffect eff = OmLayer (freshId unit) (Effect.liftEffect eff)
193−
194−instance MonadAff (OmLayer req err) where
195− liftAff aff = OmLayer (freshId unit) (Aff.liftAff aff)
196−
197−instance MonadAsk (Record req) (OmLayer req err) where
198− ask = OmLayer (freshId unit) Reader.ask
199−
200−instance MonadReader (Record req) (OmLayer req err) where
201− local f layer = OmLayer (freshId unit) (Reader.local f (buildLayer layer))
202−
203−instance MonadThrow (Variant (Exception err)) (OmLayer req err) where
204− throwError e = OmLayer (freshId unit) (throwError e)
205−
206−instance MonadError (Variant (Exception err)) (OmLayer req err) where
207− catchError layer handler = OmLayer (freshId unit) (catchError (buildLayer layer) (\e -> buildLayer (handler e)))
208−
209−instance MonadRec (OmLayer req err) where
210− tailRecM f a = OmLayer (freshId unit) (tailRecM (\x -> buildLayer (f x)) a)
211−
212−instance Semigroup a => Semigroup (OmLayer req err a) where
213− append a b = OmLayer (freshId unit) (append (buildLayer a) (buildLayer b))
214−
215−instance Alt (OmLayer req err) where
216− alt a b = OmLayer (freshId unit) (Alt.alt (buildLayer a) (buildLayer b))
217−
218−instance Plus (OmLayer req err) where
219− empty = OmLayer (freshId unit) Plus.empty
220−
221177instance Functor (ParOmLayer req err) where
222178 map f (ParOmLayer p) = ParOmLayer (map f p)
223179
@@ -227,14 +183,6 @@ instance Apply (ParOmLayer req err) where
227183instance Applicative (ParOmLayer req err) where
228184 pure a = ParOmLayer (pure a)
229185
230−instance Alt (ParOmLayer req err) where
231− alt (ParOmLayer a) (ParOmLayer b) = ParOmLayer (Alt.alt a b)
232−
233−instance Plus (ParOmLayer req err) where
234− empty = ParOmLayer Plus.empty
235−
236−instance Alternative (ParOmLayer req err)
237−
238186instance Parallel (ParOmLayer req err) (OmLayer req err) where
239187 parallel (OmLayer _ om) = ParOmLayer (Parallel.parallel om)
240188 sequential (ParOmLayer p) = OmLayer (freshId unit) (Parallel.sequential p)
@@ -392,13 +340,9 @@ else instance
392340-- =============================================================================
393341
394342-- | Run a layer with a given context, with custom error if requirements aren't met.
395−-- | `runLayer` requires a closed requirement row. If you have an open layer like
396−-- | `OmLayer (db :: Db | r) err a`, specialize it to a closed row before running
397−-- | it directly.
398343runLayer
399344 :: forall req err a available
400345 . CheckAllProvided req available
401− => Keys req
402346 => Record available
403347 -> OmLayer req err a
404348 -> Om (Record available) err a
@@ -496,17 +440,6 @@ combineRequirements layer1 layer2 = OmLayer (freshId unit) do
496440 rec2 <- Om.expand (buildLayer layer2)
497441 pure (Record.merge rec1 rec2)
498442
499−withValue
500− :: forall req err prov1 prov2 provMerged
501− . Union prov1 prov2 provMerged
502− => Nub provMerged provMerged
503− => Record prov1
504− -> OmLayer req err (Record prov2)
505− -> OmLayer req err (Record provMerged)
506−withValue defaults layer = OmLayer (freshId unit) do
507− rec <- buildLayer layer
508− pure (Record.merge defaults rec)
509−
510443-- =============================================================================
511444-- Vertical composition — feed output of one layer into input of another
512445-- =============================================================================
test/Test/Yoga/Om/Layer/InstancesSpec.purs−93
@@ -2,14 +2,11 @@ module Test.Yoga.Om.Layer.InstancesSpec where
22
33import Prelude
44
5−import Control.Alt ((<|>))
6−import Control.Monad.Reader (ask, local)
75import Control.Parallel (parApply)
86import Effect.Class (liftEffect)
97import Effect.Ref as Ref
108import Test.Spec (Spec, describe, it)
119import Test.Spec.Assertions (shouldEqual)
12−import Effect.Exception as Exception
1310import Yoga.Om as Om
1411import Yoga.Om.Layer (OmLayer, makeLayer, runLayer)
1512
@@ -49,96 +46,6 @@ spec = do
4946 result <- Om.runOm {} { exception: \_ -> pure { result: 0 } } (runLayer {} layer)
5047 result.result `shouldEqual` 15
5148
52− it "runs layers against a superset context" do
53− let
54− layer :: OmLayer (a :: Int) () { out :: Int }
55− layer = makeLayer do
56− { a } <- Om.ask
57− pure { out: a + 1 }
58−
59− ctx = { a: 41, extra: "ok" }
60−
61− result <- Om.runOm ctx { exception: \_ -> pure { out: 0 } } (runLayer ctx layer)
62− result.out `shouldEqual` 42
63−
64− describe "MonadEffect / MonadAff" do
65−
66− it "liftEffect works directly in layer bind" do
67− ref <- liftEffect $ Ref.new 0
68− let
69− layer :: OmLayer () () Int
70− layer = do
71− liftEffect $ Ref.write 42 ref
72− liftEffect $ Ref.read ref
73−
74− result <- Om.runOm {} { exception: \_ -> pure 0 } (runLayer {} layer)
75− result `shouldEqual` 42
76−
77− describe "MonadAsk / MonadReader" do
78−
79− it "ask reads the context directly" do
80− let
81− layer :: OmLayer (port :: Int) () Int
82− layer = do
83− ctx <- ask
84− pure ctx.port
85−
86− result <- Om.runOm { port: 8080 } { exception: \_ -> pure 0 } (runLayer { port: 8080 } layer)
87− result `shouldEqual` 8080
88−
89− it "local modifies context for a layer" do
90− let
91− inner :: OmLayer (port :: Int) () Int
92− inner = do
93− ctx <- ask
94− pure ctx.port
95−
96− layer :: OmLayer (port :: Int) () Int
97− layer = local (\r -> r { port = r.port + 1 }) inner
98−
99− result <- Om.runOm { port: 8080 } { exception: \_ -> pure 0 } (runLayer { port: 8080 } layer)
100− result `shouldEqual` 8081
101−
102− describe "MonadThrow / MonadError" do
103−
104− it "throwError raises into the error channel" do
105− let
106− layer :: OmLayer () (myErr :: String) Int
107− layer = Om.throw { myErr: "boom" }
108−
109− result <- Om.runOm {}
110− { exception: \_ -> pure (-1), myErr: \_ -> pure (-2) }
111− (runLayer {} layer)
112− result `shouldEqual` (-2)
113−
114− describe "Alt" do
115−
116− it "falls back to second layer on failure" do
117− let
118− failing :: OmLayer () () Int
119− failing = Om.throw { exception: Exception.error "nope" }
120−
121− fallback :: OmLayer () () Int
122− fallback = pure 99
123−
124− layer = failing <|> fallback
125−
126− result <- Om.runOm {} { exception: \_ -> pure (-1) } (runLayer {} layer)
127− result `shouldEqual` 99
128−
129− describe "Semigroup" do
130−
131− it "appends layer outputs" do
132− let
133− a :: OmLayer () () String
134− a = pure "hello"
135−
136− b :: OmLayer () () String
137− b = pure " world"
138−
139− result <- Om.runOm {} { exception: \_ -> pure "" } (runLayer {} (a <> b))
140− result `shouldEqual` "hello world"
141−
14249 describe "Parallel" do
14350
14451 it "runs layers in parallel via parApply" do
test/Test/Yoga/Om/Layer/PureInferenceSpec.pursdeleted−22
@@ -1,22 +0,0 @@
1−module Test.Yoga.Om.Layer.PureInferenceSpec where
2−
3−import Prelude
4−
5−import Test.Spec (Spec, describe, it)
6−import Test.Spec.Assertions (shouldEqual)
7−import Yoga.Om as Om
8−import Yoga.Om.Layer (OmLayer, withValue, makeLayer, runLayer)
9−
10−spec :: Spec Unit
11−spec = describe "withValue" do
12−
13− it "combines a plain record with a layer without needing VTA" do
14− let
15− layer :: OmLayer () () { value :: Int }
16− layer = makeLayer (pure { value: 42 })
17−
18− result = layer # withValue { extra: "hello" }
19−
20− out <- Om.runOm {} { exception: \_ -> pure { value: -1, extra: "" } } (runLayer {} result)
21− out.value `shouldEqual` 42
22− out.extra `shouldEqual` "hello"