git.iko.soy/purestack-dev/purescript-plum
on master help sign in
Monad construction
commit2907b1213fc7e6d76c314d66ca9cb429aef90477 authoriko <mail@iko.soy> dateWed 21 May 2025, 13:45 (1 year ago) parentef55c2a
4 files changed+613−327
plum/index.js+449−306 plum/src/Main.purs+5−8 plum/src/Plum.purs+16−10 plum/src/Plum/View.purs+143−3
plum/index.js+449−306
@@ -23,9 +23,6 @@
2323 }
2424 };
2525
26− // output/Data.Boolean/index.js
27− var otherwise = true;
28−
2926 // output/Data.Function/index.js
3027 var flip = function(f) {
3128 return function(b) {
@@ -34,11 +31,6 @@
3431 };
3532 };
3633 };
37− var $$const = function(a) {
38− return function(v) {
39− return a;
40− };
41− };
4234
4335 // output/Data.Functor/foreign.js
4436 var arrayMap = function(f) {
@@ -55,6 +47,15 @@
5547 // output/Data.Unit/foreign.js
5648 var unit = void 0;
5749
50+ // output/Type.Proxy/index.js
51+ var $$Proxy = /* @__PURE__ */ function() {
52+ function $$Proxy2() {
53+ }
54+ ;
55+ $$Proxy2.value = new $$Proxy2();
56+ return $$Proxy2;
57+ }();
58+
5859 // output/Data.Functor/index.js
5960 var map = function(dict) {
6061 return dict.map;
@@ -82,52 +83,6 @@
8283 };
8384 };
8485
85− // output/Data.Array/foreign.js
86− var rangeImpl = function(start2, end) {
87− var step2 = start2 > end ? -1 : 1;
88− var result = new Array(step2 * (end - start2) + 1);
89− var i = start2, n = 0;
90− while (i !== end) {
91− result[n++] = i;
92− i += step2;
93− }
94− result[n] = i;
95− return result;
96− };
97− var replicateFill = function(count, value12) {
98− if (count < 1) {
99− return [];
100− }
101− var result = new Array(count);
102− return result.fill(value12);
103− };
104− var replicatePolyfill = function(count, value12) {
105− var result = [];
106− var n = 0;
107− for (var i = 0; i < count; i++) {
108− result[n++] = value12;
109− }
110− return result;
111− };
112− var replicateImpl = typeof Array.prototype.fill === "function" ? replicateFill : replicatePolyfill;
113−
114− // output/Data.Semigroup/foreign.js
115− var concatArray = function(xs) {
116− return function(ys) {
117− if (xs.length === 0) return ys;
118− if (ys.length === 0) return xs;
119− return xs.concat(ys);
120− };
121− };
122−
123− // output/Data.Semigroup/index.js
124− var semigroupArray = {
125− append: concatArray
126− };
127− var append = function(dict) {
128− return dict.append;
129− };
130−
13186 // output/Control.Bind/foreign.js
13287 var arrayBind = typeof Array.prototype.flatMap === "function" ? function(arr) {
13388 return function(f) {
@@ -149,179 +104,178 @@
149104 };
150105
151106 // output/Control.Bind/index.js
107+ var discard = function(dict) {
108+ return dict.discard;
109+ };
152110 var bind = function(dict) {
153111 return dict.bind;
154112 };
155113 var bindFlipped = function(dictBind) {
156114 return flip(bind(dictBind));
157115 };
158−
159− // output/Control.Monad/index.js
160− var ap = function(dictMonad) {
161− var bind3 = bind(dictMonad.Bind1());
162− var pure3 = pure(dictMonad.Applicative0());
163− return function(f) {
164− return function(a) {
165− return bind3(f)(function(f$prime) {
166− return bind3(a)(function(a$prime) {
167− return pure3(f$prime(a$prime));
168− });
169− });
170− };
171− };
116+ var discardUnit = {
117+ discard: function(dictBind) {
118+ return bind(dictBind);
119+ }
172120 };
173121
174− // output/Data.Bounded/foreign.js
175− var topInt = 2147483647;
176− var bottomInt = -2147483648;
177− var topChar = String.fromCharCode(65535);
178− var bottomChar = String.fromCharCode(0);
179− var topNumber = Number.POSITIVE_INFINITY;
180− var bottomNumber = Number.NEGATIVE_INFINITY;
122+ // output/Data.Symbol/index.js
123+ var reflectSymbol = function(dict) {
124+ return dict.reflectSymbol;
125+ };
181126
182− // output/Data.Ord/foreign.js
183− var unsafeCompareImpl = function(lt) {
184− return function(eq2) {
185− return function(gt) {
186− return function(x) {
187− return function(y) {
188− return x < y ? lt : x === y ? eq2 : gt;
189− };
190− };
127+ // output/Record.Unsafe/foreign.js
128+ var unsafeGet = function(label4) {
129+ return function(rec) {
130+ return rec[label4];
131+ };
132+ };
133+ var unsafeSet = function(label4) {
134+ return function(value12) {
135+ return function(rec) {
136+ var copy = {};
137+ for (var key in rec) {
138+ if ({}.hasOwnProperty.call(rec, key)) {
139+ copy[key] = rec[key];
140+ }
141+ }
142+ copy[label4] = value12;
143+ return copy;
191144 };
192145 };
193146 };
194− var ordIntImpl = unsafeCompareImpl;
195147
196− // output/Data.Eq/foreign.js
197− var refEq = function(r1) {
198− return function(r2) {
199− return r1 === r2;
148+ // output/Data.Semigroup/foreign.js
149+ var concatArray = function(xs) {
150+ return function(ys) {
151+ if (xs.length === 0) return ys;
152+ if (ys.length === 0) return xs;
153+ return xs.concat(ys);
200154 };
201155 };
202− var eqIntImpl = refEq;
203−
204− // output/Data.Eq/index.js
205− var eqInt = {
206− eq: eqIntImpl
207− };
208156
209− // output/Data.Ordering/index.js
210− var LT = /* @__PURE__ */ function() {
211− function LT2() {
212− }
213− ;
214− LT2.value = new LT2();
215− return LT2;
216− }();
217− var GT = /* @__PURE__ */ function() {
218− function GT2() {
219− }
220− ;
221− GT2.value = new GT2();
222− return GT2;
223− }();
224− var EQ = /* @__PURE__ */ function() {
225− function EQ2() {
157+ // output/Data.Semigroup/index.js
158+ var semigroupUnit = {
159+ append: function(v) {
160+ return function(v1) {
161+ return unit;
162+ };
226163 }
227− ;
228− EQ2.value = new EQ2();
229− return EQ2;
230− }();
231−
232− // output/Data.Ord/index.js
233− var ordInt = /* @__PURE__ */ function() {
234− return {
235− compare: ordIntImpl(LT.value)(EQ.value)(GT.value),
236− Eq0: function() {
237− return eqInt;
238− }
239− };
240− }();
241−
242− // output/Data.Bounded/index.js
243− var top = function(dict) {
244− return dict.top;
245164 };
246− var boundedInt = {
247− top: topInt,
248− bottom: bottomInt,
249− Ord0: function() {
250− return ordInt;
165+ var semigroupRecordNil = {
166+ appendRecord: function(v) {
167+ return function(v1) {
168+ return function(v2) {
169+ return {};
170+ };
171+ };
251172 }
252173 };
253− var bottom = function(dict) {
254− return dict.bottom;
255− };
256−
257− // output/Data.Show/foreign.js
258− var showIntImpl = function(n) {
259− return n.toString();
260− };
261− var showNumberImpl = function(n) {
262− var str = n.toString();
263− return isNaN(str + ".0") ? str : str + ".0";
174+ var semigroupArray = {
175+ append: concatArray
264176 };
265−
266− // output/Data.Show/index.js
267− var showNumber = {
268− show: showNumberImpl
177+ var appendRecord = function(dict) {
178+ return dict.appendRecord;
269179 };
270− var showInt = {
271− show: showIntImpl
180+ var semigroupRecord = function() {
181+ return function(dictSemigroupRecord) {
182+ return {
183+ append: appendRecord(dictSemigroupRecord)($$Proxy.value)
184+ };
185+ };
272186 };
273− var show = function(dict) {
274− return dict.show;
187+ var append = function(dict) {
188+ return dict.append;
275189 };
276−
277− // output/Data.Maybe/index.js
278− var identity2 = /* @__PURE__ */ identity(categoryFn);
279− var Nothing = /* @__PURE__ */ function() {
280− function Nothing2() {
281− }
282− ;
283− Nothing2.value = new Nothing2();
284− return Nothing2;
285− }();
286− var Just = /* @__PURE__ */ function() {
287− function Just2(value0) {
288− this.value0 = value0;
289− }
290− ;
291− Just2.create = function(value0) {
292− return new Just2(value0);
293− };
294− return Just2;
295− }();
296− var maybe = function(v) {
297− return function(v1) {
298− return function(v2) {
299− if (v2 instanceof Nothing) {
300− return v;
301− }
302− ;
303− if (v2 instanceof Just) {
304− return v1(v2.value0);
305− }
306− ;
307− throw new Error("Failed pattern match at Data.Maybe (line 237, column 1 - line 237, column 51): " + [v.constructor.name, v1.constructor.name, v2.constructor.name]);
190+ var semigroupRecordCons = function(dictIsSymbol) {
191+ var reflectSymbol2 = reflectSymbol(dictIsSymbol);
192+ return function() {
193+ return function(dictSemigroupRecord) {
194+ var appendRecord1 = appendRecord(dictSemigroupRecord);
195+ return function(dictSemigroup) {
196+ var append12 = append(dictSemigroup);
197+ return {
198+ appendRecord: function(v) {
199+ return function(ra) {
200+ return function(rb) {
201+ var tail = appendRecord1($$Proxy.value)(ra)(rb);
202+ var key = reflectSymbol2($$Proxy.value);
203+ var insert = unsafeSet(key);
204+ var get = unsafeGet(key);
205+ return insert(append12(get(ra))(get(rb)))(tail);
206+ };
207+ };
208+ }
209+ };
210+ };
308211 };
309212 };
310213 };
311− var fromMaybe = function(a) {
312− return maybe(a)(identity2);
313− };
314214
315215 // output/Data.Monoid/index.js
216+ var semigroupRecord2 = /* @__PURE__ */ semigroupRecord();
217+ var monoidUnit = {
218+ mempty: unit,
219+ Semigroup0: function() {
220+ return semigroupUnit;
221+ }
222+ };
223+ var monoidRecordNil = {
224+ memptyRecord: function(v) {
225+ return {};
226+ },
227+ SemigroupRecord0: function() {
228+ return semigroupRecordNil;
229+ }
230+ };
316231 var monoidArray = {
317232 mempty: [],
318233 Semigroup0: function() {
319234 return semigroupArray;
320235 }
321236 };
237+ var memptyRecord = function(dict) {
238+ return dict.memptyRecord;
239+ };
240+ var monoidRecord = function() {
241+ return function(dictMonoidRecord) {
242+ var semigroupRecord1 = semigroupRecord2(dictMonoidRecord.SemigroupRecord0());
243+ return {
244+ mempty: memptyRecord(dictMonoidRecord)($$Proxy.value),
245+ Semigroup0: function() {
246+ return semigroupRecord1;
247+ }
248+ };
249+ };
250+ };
322251 var mempty = function(dict) {
323252 return dict.mempty;
324253 };
254+ var monoidRecordCons = function(dictIsSymbol) {
255+ var reflectSymbol2 = reflectSymbol(dictIsSymbol);
256+ var semigroupRecordCons3 = semigroupRecordCons(dictIsSymbol)();
257+ return function(dictMonoid) {
258+ var mempty12 = mempty(dictMonoid);
259+ var Semigroup0 = dictMonoid.Semigroup0();
260+ return function() {
261+ return function(dictMonoidRecord) {
262+ var memptyRecord1 = memptyRecord(dictMonoidRecord);
263+ var semigroupRecordCons1 = semigroupRecordCons3(dictMonoidRecord.SemigroupRecord0())(Semigroup0);
264+ return {
265+ memptyRecord: function(v) {
266+ var tail = memptyRecord1($$Proxy.value);
267+ var key = reflectSymbol2($$Proxy.value);
268+ var insert = unsafeSet(key);
269+ return insert(mempty12)(tail);
270+ },
271+ SemigroupRecord0: function() {
272+ return semigroupRecordCons1;
273+ }
274+ };
275+ };
276+ };
277+ };
278+ };
325279
326280 // output/Effect/foreign.js
327281 var pureE = function(a) {
@@ -337,6 +291,21 @@
337291 };
338292 };
339293
294+ // output/Control.Monad/index.js
295+ var ap = function(dictMonad) {
296+ var bind3 = bind(dictMonad.Bind1());
297+ var pure3 = pure(dictMonad.Applicative0());
298+ return function(f) {
299+ return function(a) {
300+ return bind3(f)(function(f$prime) {
301+ return bind3(a)(function(a$prime) {
302+ return pure3(f$prime(a$prime));
303+ });
304+ });
305+ };
306+ };
307+ };
308+
340309 // output/Effect/index.js
341310 var $runtime_lazy = function(name14, moduleName, init) {
342311 var state2 = 0;
@@ -385,6 +354,88 @@
385354 });
386355 var functorEffect = /* @__PURE__ */ $lazy_functorEffect(20);
387356
357+ // output/Data.Array/foreign.js
358+ var replicateFill = function(count, value12) {
359+ if (count < 1) {
360+ return [];
361+ }
362+ var result = new Array(count);
363+ return result.fill(value12);
364+ };
365+ var replicatePolyfill = function(count, value12) {
366+ var result = [];
367+ var n = 0;
368+ for (var i = 0; i < count; i++) {
369+ result[n++] = value12;
370+ }
371+ return result;
372+ };
373+ var replicateImpl = typeof Array.prototype.fill === "function" ? replicateFill : replicatePolyfill;
374+
375+ // output/Data.Bounded/foreign.js
376+ var topChar = String.fromCharCode(65535);
377+ var bottomChar = String.fromCharCode(0);
378+ var topNumber = Number.POSITIVE_INFINITY;
379+ var bottomNumber = Number.NEGATIVE_INFINITY;
380+
381+ // output/Data.Show/foreign.js
382+ var showIntImpl = function(n) {
383+ return n.toString();
384+ };
385+ var showNumberImpl = function(n) {
386+ var str = n.toString();
387+ return isNaN(str + ".0") ? str : str + ".0";
388+ };
389+
390+ // output/Data.Show/index.js
391+ var showNumber = {
392+ show: showNumberImpl
393+ };
394+ var showInt = {
395+ show: showIntImpl
396+ };
397+ var show = function(dict) {
398+ return dict.show;
399+ };
400+
401+ // output/Data.Maybe/index.js
402+ var identity2 = /* @__PURE__ */ identity(categoryFn);
403+ var Nothing = /* @__PURE__ */ function() {
404+ function Nothing2() {
405+ }
406+ ;
407+ Nothing2.value = new Nothing2();
408+ return Nothing2;
409+ }();
410+ var Just = /* @__PURE__ */ function() {
411+ function Just2(value0) {
412+ this.value0 = value0;
413+ }
414+ ;
415+ Just2.create = function(value0) {
416+ return new Just2(value0);
417+ };
418+ return Just2;
419+ }();
420+ var maybe = function(v) {
421+ return function(v1) {
422+ return function(v2) {
423+ if (v2 instanceof Nothing) {
424+ return v;
425+ }
426+ ;
427+ if (v2 instanceof Just) {
428+ return v1(v2.value0);
429+ }
430+ ;
431+ throw new Error("Failed pattern match at Data.Maybe (line 237, column 1 - line 237, column 51): " + [v.constructor.name, v1.constructor.name, v2.constructor.name]);
432+ };
433+ };
434+ };
435+ var fromMaybe = function(a) {
436+ return maybe(a)(identity2);
437+ };
438+
388439 // output/Effect.Ref/foreign.js
389440 var _new = function(val) {
390441 return function() {
@@ -527,13 +578,13 @@
527578 var foldr2 = foldr(dictFoldable);
528579 return function(dictMonoid) {
529580 var append3 = append(dictMonoid.Semigroup0());
530− var mempty3 = mempty(dictMonoid);
581+ var mempty5 = mempty(dictMonoid);
531582 return function(f) {
532583 return foldr2(function(x) {
533584 return function(acc) {
534585 return append3(f(x))(acc);
535586 };
536− })(mempty3);
587+ })(mempty5);
537588 };
538589 };
539590 };
@@ -559,10 +610,15 @@
559610
560611 // output/Data.Array/index.js
561612 var foldMap1 = /* @__PURE__ */ foldMap(foldableArray);
562− var range2 = /* @__PURE__ */ runFn2(rangeImpl);
613+ var append2 = /* @__PURE__ */ append(semigroupArray);
563614 var foldMap2 = function(dictMonoid) {
564615 return foldMap1(dictMonoid);
565616 };
617+ var cons = function(x) {
618+ return function(xs) {
619+ return append2([x])(xs);
620+ };
621+ };
566622
567623 // output/Maquette/foreign.js
568624 var NAMESPACE_W3 = "http://www.w3.org/";
@@ -1178,10 +1234,10 @@
11781234 } else if (properties && (typeof properties === "string" || properties.vnodeSelector) || children && (typeof children === "string" || children.vnodeSelector)) {
11791235 throw new Error("h called with invalid arguments");
11801236 }
1181− var text5;
1237+ var text6;
11821238 var flattenedChildren;
11831239 if (children && children.length === 1 && typeof children[0] === "string") {
1184− text5 = children[0];
1240+ text6 = children[0];
11851241 } else if (children) {
11861242 flattenedChildren = [];
11871243 appendChildren(selector, children, flattenedChildren);
@@ -1193,7 +1249,7 @@
11931249 vnodeSelector: selector,
11941250 properties,
11951251 children: flattenedChildren,
1196− text: text5 === "" ? void 0 : text5,
1252+ text: text6 === "" ? void 0 : text6,
11971253 domNode: null
11981254 };
11991255 }
@@ -1344,51 +1400,6 @@
13441400 var string = unsafeCoerce2;
13451401 var h2 = _h;
13461402
1347− // output/Data.Int/foreign.js
1348− var fromNumberImpl = function(just) {
1349− return function(nothing) {
1350− return function(n) {
1351− return (n | 0) === n ? just(n) : nothing;
1352− };
1353− };
1354− };
1355− var toNumber = function(n) {
1356− return n;
1357− };
1358−
1359− // output/Data.Number/foreign.js
1360− var isFiniteImpl = isFinite;
1361− var round = Math.round;
1362−
1363− // output/Data.Int/index.js
1364− var top2 = /* @__PURE__ */ top(boundedInt);
1365− var bottom2 = /* @__PURE__ */ bottom(boundedInt);
1366− var fromNumber = /* @__PURE__ */ function() {
1367− return fromNumberImpl(Just.create)(Nothing.value);
1368− }();
1369− var unsafeClamp = function(x) {
1370− if (!isFiniteImpl(x)) {
1371− return 0;
1372− }
1373− ;
1374− if (x >= toNumber(top2)) {
1375− return top2;
1376− }
1377− ;
1378− if (x <= toNumber(bottom2)) {
1379− return bottom2;
1380− }
1381− ;
1382− if (otherwise) {
1383− return fromMaybe(0)(fromNumber(x));
1384− }
1385− ;
1386− throw new Error("Failed pattern match at Data.Int (line 72, column 1 - line 72, column 29): " + [x.constructor.name]);
1387− };
1388− var round2 = function($37) {
1389− return unsafeClamp(round($37));
1390− };
1391−
13921403 // output/Foreign.Object/foreign.js
13931404 function _copyST(m) {
13941405 return function() {
@@ -1516,10 +1527,31 @@
15161527 var unsafeUnion = /* @__PURE__ */ runFn2(unsafeUnionFn);
15171528
15181529 // output/Plum.View/index.js
1530+ var semigroupRecord3 = /* @__PURE__ */ semigroupRecord();
1531+ var childrenIsSymbol = {
1532+ reflectSymbol: function() {
1533+ return "children";
1534+ }
1535+ };
1536+ var meatIsSymbol = {
1537+ reflectSymbol: function() {
1538+ return "meat";
1539+ }
1540+ };
1541+ var nervesIsSymbol = {
1542+ reflectSymbol: function() {
1543+ return "nerves";
1544+ }
1545+ };
1546+ var semigroupRecordCons2 = /* @__PURE__ */ semigroupRecordCons(childrenIsSymbol)()(/* @__PURE__ */ semigroupRecordCons(meatIsSymbol)()(/* @__PURE__ */ semigroupRecordCons(nervesIsSymbol)()(semigroupRecordNil)(semigroupArray))(semigroupArray));
15191547 var show2 = /* @__PURE__ */ show(showInt);
15201548 var show1 = /* @__PURE__ */ show(showNumber);
1549+ var monoidRecord2 = /* @__PURE__ */ monoidRecord();
1550+ var monoidRecordCons2 = /* @__PURE__ */ monoidRecordCons(childrenIsSymbol);
1551+ var monoidRecordCons1 = /* @__PURE__ */ monoidRecordCons(meatIsSymbol)(monoidArray)()(/* @__PURE__ */ monoidRecordCons(nervesIsSymbol)(monoidArray)()(monoidRecordNil));
1552+ var mempty2 = /* @__PURE__ */ mempty(/* @__PURE__ */ monoidRecord2(/* @__PURE__ */ monoidRecordCons2(monoidArray)()(monoidRecordCons1)));
15211553 var append1 = /* @__PURE__ */ append(semigroupArray);
1522− var mempty2 = /* @__PURE__ */ mempty(monoidArray);
1554+ var mempty1 = /* @__PURE__ */ mempty(monoidArray);
15231555 var map2 = /* @__PURE__ */ map(functorArray);
15241556 var Px = /* @__PURE__ */ function() {
15251557 function Px2(value0) {
@@ -1761,6 +1793,19 @@
17611793 };
17621794 return Clip2;
17631795 }();
1796+ var UI = /* @__PURE__ */ function() {
1797+ function UI2(value0, value1) {
1798+ this.value0 = value0;
1799+ this.value1 = value1;
1800+ }
1801+ ;
1802+ UI2.create = function(value0) {
1803+ return function(value1) {
1804+ return new UI2(value0, value1);
1805+ };
1806+ };
1807+ return UI2;
1808+ }();
17641809 var Column = /* @__PURE__ */ function() {
17651810 function Column2(value0) {
17661811 this.value0 = value0;
@@ -1843,6 +1888,39 @@
18431888 };
18441889 return Download2;
18451890 }();
1891+ var Image2 = /* @__PURE__ */ function() {
1892+ function Image3(value0, value1) {
1893+ this.value0 = value0;
1894+ this.value1 = value1;
1895+ }
1896+ ;
1897+ Image3.create = function(value0) {
1898+ return function(value1) {
1899+ return new Image3(value0, value1);
1900+ };
1901+ };
1902+ return Image3;
1903+ }();
1904+ var None = /* @__PURE__ */ function() {
1905+ function None3() {
1906+ }
1907+ ;
1908+ None3.value = new None3();
1909+ return None3;
1910+ }();
1911+ var semigroupUIWith = function(dictSemigroup) {
1912+ var append3 = append(semigroupRecord3(semigroupRecordCons2(dictSemigroup)));
1913+ return function(dictSemigroup1) {
1914+ var append4 = append(dictSemigroup1);
1915+ return {
1916+ append: function(v) {
1917+ return function(v1) {
1918+ return new UI(append3(v.value0)(v1.value0), append4(v.value1)(v1.value1));
1919+ };
1920+ }
1921+ };
1922+ };
1923+ };
18461924 var semigroupSkin = {
18471925 append: function(v) {
18481926 return function(v1) {
@@ -1850,12 +1928,12 @@
18501928 };
18511929 }
18521930 };
1853− var append2 = /* @__PURE__ */ append(semigroupSkin);
1931+ var append22 = /* @__PURE__ */ append(semigroupSkin);
18541932 var semigroupMutation = {
18551933 append: function(v) {
18561934 return function(v1) {
18571935 return {
1858− extraSkin: append2(v.extraSkin)(v1.extraSkin)
1936+ extraSkin: append22(v.extraSkin)(v1.extraSkin)
18591937 };
18601938 };
18611939 }
@@ -1865,32 +1943,82 @@
18651943 return "rgba(" + (show2(v.r) + ("," + (show2(v.g) + ("," + (show2(v.b) + ("," + (show1(v.a) + ")")))))));
18661944 }
18671945 };
1946+ var monoidUIWith = function(dictMonoid) {
1947+ var mempty42 = mempty(monoidRecord2(monoidRecordCons2(dictMonoid)()(monoidRecordCons1)));
1948+ var semigroupUIWith1 = semigroupUIWith(dictMonoid.Semigroup0());
1949+ return function(dictMonoid1) {
1950+ var semigroupUIWith2 = semigroupUIWith1(dictMonoid1.Semigroup0());
1951+ return {
1952+ mempty: new UI(mempty42, mempty(dictMonoid1)),
1953+ Semigroup0: function() {
1954+ return semigroupUIWith2;
1955+ }
1956+ };
1957+ };
1958+ };
18681959 var monoidSkin = {
18691960 mempty: empty2,
18701961 Semigroup0: function() {
18711962 return semigroupSkin;
18721963 }
18731964 };
1874− var mempty1 = /* @__PURE__ */ mempty(monoidSkin);
1965+ var mempty22 = /* @__PURE__ */ mempty(monoidSkin);
18751966 var foldMap3 = /* @__PURE__ */ foldMap2(monoidSkin);
18761967 var monoidMutation = {
18771968 mempty: {
1878− extraSkin: mempty1
1969+ extraSkin: mempty22
18791970 },
18801971 Semigroup0: function() {
18811972 return semigroupMutation;
18821973 }
18831974 };
1884− var mempty22 = /* @__PURE__ */ mempty(monoidMutation);
1885− var view = function(nerves) {
1886− return function(meat) {
1887− return function(bones) {
1888− return {
1889− nerves,
1890− meat,
1891− bones
1892− };
1975+ var mempty3 = /* @__PURE__ */ mempty(monoidMutation);
1976+ var functorUIWith = {
1977+ map: function(f) {
1978+ return function(v) {
1979+ return new UI(v.value0, f(v.value1));
18931980 };
1981+ }
1982+ };
1983+ var applyUIWith = function(dictMonoid) {
1984+ var append3 = append(semigroupRecord3(semigroupRecordCons2(dictMonoid.Semigroup0())));
1985+ return {
1986+ apply: function(v) {
1987+ return function(v1) {
1988+ return new UI(append3(v.value0)(v1.value0), v.value1(v1.value1));
1989+ };
1990+ },
1991+ Functor0: function() {
1992+ return functorUIWith;
1993+ }
1994+ };
1995+ };
1996+ var bindUIWith = function(dictMonoid) {
1997+ var append3 = append(semigroupRecord3(semigroupRecordCons2(dictMonoid.Semigroup0())));
1998+ var applyUIWith1 = applyUIWith(dictMonoid);
1999+ return {
2000+ bind: function(v) {
2001+ return function(f) {
2002+ var v1 = f(v.value1);
2003+ return new UI(append3(v.value0)(v1.value0), v1.value1);
2004+ };
2005+ },
2006+ Apply0: function() {
2007+ return applyUIWith1;
2008+ }
2009+ };
2010+ };
2011+ var text = function(s) {
2012+ return function(v) {
2013+ return new UI({
2014+ nerves: mempty2.nerves,
2015+ meat: mempty2.meat,
2016+ children: [{
2017+ meat: v.value0.meat,
2018+ nerves: v.value0.nerves,
2019+ bones: new Text(s)
2020+ }]
2021+ }, v.value1);
18942022 };
18952023 };
18962024 var sk = function(key) {
@@ -1898,18 +2026,6 @@
18982026 return singleton2(key)(val);
18992027 };
19002028 };
1901− var rgb = function(r) {
1902− return function(g) {
1903− return function(b) {
1904− return {
1905− r: round2(r * 255),
1906− g: round2(g * 255),
1907− b: round2(b * 255),
1908− a: 1
1909− };
1910− };
1911− };
1912− };
19132029 var render = function(dict) {
19142030 return dict.render;
19152031 };
@@ -1936,7 +2052,7 @@
19362052 return "min(" + (show2(v.value0) + ("px," + (render(renderableLength)(v.value1) + ")")));
19372053 }
19382054 ;
1939− throw new Error("Failed pattern match at Plum.View (line 131, column 12 - line 136, column 62): " + [v.constructor.name]);
2055+ throw new Error("Failed pattern match at Plum.View (line 258, column 12 - line 263, column 62): " + [v.constructor.name]);
19402056 }
19412057 };
19422058 var render2 = /* @__PURE__ */ render(renderableLength);
@@ -1952,11 +2068,11 @@
19522068 ;
19532069 if (v instanceof Align) {
19542070 if (ctx instanceof Generic) {
1955− return mempty1;
2071+ return mempty22;
19562072 }
19572073 ;
19582074 if (ctx instanceof Span) {
1959− return mempty1;
2075+ return mempty22;
19602076 }
19612077 ;
19622078 if (ctx instanceof Grid) {
@@ -1969,7 +2085,7 @@
19692085 return "align-items";
19702086 }
19712087 ;
1972− throw new Error("Failed pattern match at Plum.View (line 88, column 9 - line 90, column 29): " + [v.value0.constructor.name]);
2088+ throw new Error("Failed pattern match at Plum.View (line 215, column 9 - line 217, column 29): " + [v.value0.constructor.name]);
19732089 }())(function() {
19742090 if (v.value1 instanceof Start) {
19752091 return "start";
@@ -1983,7 +2099,7 @@
19832099 return "end";
19842100 }
19852101 ;
1986− throw new Error("Failed pattern match at Plum.View (line 92, column 9 - line 95, column 23): " + [v.value1.constructor.name]);
2102+ throw new Error("Failed pattern match at Plum.View (line 219, column 9 - line 222, column 23): " + [v.value1.constructor.name]);
19872103 }());
19882104 }
19892105 ;
@@ -2006,7 +2122,7 @@
20062122 return "justify-content";
20072123 }
20082124 ;
2009− throw new Error("Failed pattern match at Plum.View (line 99, column 9 - line 103, column 38): " + [v1.constructor.name]);
2125+ throw new Error("Failed pattern match at Plum.View (line 226, column 9 - line 230, column 38): " + [v1.constructor.name]);
20102126 }())(function() {
20112127 if (v.value1 instanceof Start) {
20122128 return "flex-start";
@@ -2020,11 +2136,11 @@
20202136 return "flex-end";
20212137 }
20222138 ;
2023− throw new Error("Failed pattern match at Plum.View (line 105, column 9 - line 108, column 28): " + [v.value1.constructor.name]);
2139+ throw new Error("Failed pattern match at Plum.View (line 232, column 9 - line 235, column 28): " + [v.value1.constructor.name]);
20242140 }());
20252141 }
20262142 ;
2027− throw new Error("Failed pattern match at Plum.View (line 84, column 26 - line 109, column 8): " + [ctx.constructor.name]);
2143+ throw new Error("Failed pattern match at Plum.View (line 211, column 26 - line 236, column 8): " + [ctx.constructor.name]);
20282144 }
20292145 ;
20302146 if (v instanceof Width) {
@@ -2040,7 +2156,7 @@
20402156 return sk("flex-wrap")("wrap");
20412157 }
20422158 ;
2043− return mempty1;
2159+ return mempty22;
20442160 }
20452161 ;
20462162 if (v instanceof BackgroundColor) {
@@ -2056,7 +2172,7 @@
20562172 return sk("justify-content")("space-between");
20572173 }
20582174 ;
2059− return mempty1;
2175+ return mempty22;
20602176 }
20612177 ;
20622178 if (v instanceof Opacity) {
@@ -2079,24 +2195,24 @@
20792195 return sk("overflow-y")("hidden");
20802196 }
20812197 ;
2082− throw new Error("Failed pattern match at Plum.View (line 81, column 12 - line 125, column 37): " + [v.constructor.name]);
2198+ throw new Error("Failed pattern match at Plum.View (line 208, column 12 - line 252, column 37): " + [v.constructor.name]);
20832199 };
20842200 };
2085− var hWith = function(el) {
2201+ var hWith = function(elem2) {
20862202 return function(props) {
20872203 return function(v) {
20882204 return function(children) {
2089− return h2(el)(unsafeUnion(props)({
2205+ return h2(elem2)(unsafeUnion(props)({
20902206 styles: v
20912207 }))(children);
20922208 };
20932209 };
20942210 };
20952211 };
2096− var h3 = function(el) {
2212+ var h3 = function(elem2) {
20972213 return function(v) {
20982214 return function(children) {
2099− return h2(el)({
2215+ return h2(elem2)({
21002216 styles: v
21012217 })(children);
21022218 };
@@ -2108,9 +2224,9 @@
21082224 var widthFill = [new Width(Fill.value), new Height(Fill.value)];
21092225 var alignCenter = [new Align(X.value, Center.value), new Align(Y.value, Center.value)];
21102226 var skn = function(ctx) {
2111− return append2(foldMap3(skin(ctx))(append1(v1.meat)(append1(function() {
2227+ return append22(foldMap3(skin(ctx))(append1(v1.meat)(append1(function() {
21122228 if (ctx instanceof Span) {
2113− return mempty2;
2229+ return mempty1;
21142230 }
21152231 ;
21162232 if (ctx instanceof Grid) {
@@ -2125,7 +2241,7 @@
21252241 return widthFill;
21262242 }
21272243 ;
2128− throw new Error("Failed pattern match at Plum.View (line 181, column 16 - line 185, column 35): " + [ctx.constructor.name]);
2244+ throw new Error("Failed pattern match at Plum.View (line 310, column 16 - line 314, column 35): " + [ctx.constructor.name]);
21292245 }())(function() {
21302246 if (ctx instanceof Grid) {
21312247 return alignCenter;
@@ -2136,14 +2252,14 @@
21362252 }
21372253 ;
21382254 if (ctx instanceof Span) {
2139− return mempty2;
2255+ return mempty1;
21402256 }
21412257 ;
21422258 if (ctx instanceof Generic) {
21432259 return alignCenter;
21442260 }
21452261 ;
2146− throw new Error("Failed pattern match at Plum.View (line 186, column 16 - line 190, column 37): " + [ctx.constructor.name]);
2262+ throw new Error("Failed pattern match at Plum.View (line 315, column 16 - line 319, column 37): " + [ctx.constructor.name]);
21472263 }()))))(v.extraSkin);
21482264 };
21492265 if (v1.bones instanceof Text) {
@@ -2151,21 +2267,21 @@
21512267 }
21522268 ;
21532269 if (v1.bones instanceof Wrapper) {
2154− return h3("div")(append2(skn(new Flexbox(X.value)))(append2(sk("display")("flex"))(sk("flex-direction")("row"))))([growSkin(fire)(mempty22)(v1.bones.value0)]);
2270+ return h3("div")(append22(skn(new Flexbox(X.value)))(append22(sk("display")("flex"))(sk("flex-direction")("row"))))([growSkin(fire)(mempty3)(v1.bones.value0)]);
21552271 }
21562272 ;
21572273 if (v1.bones instanceof Stack) {
2158− return h3("div")(append2(skn(Grid.value))(sk("display")("grid")))(map2(growSkin(fire)({
2159− extraSkin: append2(sk("grid-row")("1"))(sk("grid-column")("1"))
2274+ return h3("div")(append22(skn(Grid.value))(sk("display")("grid")))(map2(growSkin(fire)({
2275+ extraSkin: append22(sk("grid-row")("1"))(sk("grid-column")("1"))
21602276 }))(v1.bones.value0));
21612277 }
21622278 ;
21632279 if (v1.bones instanceof Row) {
2164− return h3("div")(append2(skn(new Flexbox(X.value)))(append2(sk("display")("flex"))(sk("flex-direction")("row"))))(map2(growSkin(fire)(mempty22))(v1.bones.value0));
2280+ return h3("div")(append22(skn(new Flexbox(X.value)))(append22(sk("display")("flex"))(sk("flex-direction")("row"))))(map2(growSkin(fire)(mempty3))(v1.bones.value0));
21652281 }
21662282 ;
21672283 if (v1.bones instanceof Column) {
2168− return h3("div")(append2(skn(new Flexbox(Y.value)))(append2(sk("display")("flex"))(sk("flex-direction")("column"))))(map2(growSkin(fire)(mempty22))(v1.bones.value0));
2284+ return h3("div")(append22(skn(new Flexbox(Y.value)))(append22(sk("display")("flex"))(sk("flex-direction")("column"))))(map2(growSkin(fire)(mempty3))(v1.bones.value0));
21692285 }
21702286 ;
21712287 if (v1.bones instanceof Link) {
@@ -2179,25 +2295,47 @@
21792295 ;
21802296 return "_self";
21812297 }()
2182− })(append2(skn(new Flexbox(X.value)))(append2(sk("display")("flex"))(sk("flex-direction")("row"))))([growSkin(fire)(mempty22)(v1.bones.value2)]);
2298+ })(append22(skn(new Flexbox(X.value)))(append22(sk("display")("flex"))(sk("flex-direction")("row"))))([growSkin(fire)(mempty3)(v1.bones.value2)]);
21832299 }
21842300 ;
21852301 if (v1.bones instanceof Download) {
21862302 return hWith("a")({
21872303 href: v1.bones.value0,
21882304 download: fromMaybe("")(v1.bones.value1.filename)
2189− })(append2(skn(new Flexbox(X.value)))(append2(sk("display")("flex"))(sk("flex-direction")("row"))))([growSkin(fire)(mempty22)(v1.bones.value2)]);
2305+ })(append22(skn(new Flexbox(X.value)))(append22(sk("display")("flex"))(sk("flex-direction")("row"))))([growSkin(fire)(mempty3)(v1.bones.value2)]);
2306+ }
2307+ ;
2308+ if (v1.bones instanceof Image2) {
2309+ return hWith("img")({
2310+ src: v1.bones.value0,
2311+ alt: v1.bones.value1.description
2312+ })(skn(Generic.value))([]);
21902313 }
21912314 ;
2192− throw new Error("Failed pattern match at Plum.View (line 193, column 5 - line 215, column 39): " + [v1.bones.constructor.name]);
2315+ if (v1.bones instanceof None) {
2316+ return h3("div")(mempty22)([]);
2317+ }
2318+ ;
2319+ throw new Error("Failed pattern match at Plum.View (line 322, column 5 - line 346, column 32): " + [v1.bones.constructor.name]);
21932320 };
21942321 };
21952322 };
21962323 var grow = function(fire) {
21972324 return function(v) {
2198− return growSkin(fire)(mempty22)(v);
2325+ return growSkin(fire)(mempty3)(v);
21992326 };
22002327 };
2328+ var column = function(v) {
2329+ return new UI({
2330+ nerves: mempty2.nerves,
2331+ meat: mempty2.meat,
2332+ children: [{
2333+ meat: v.value0.meat,
2334+ nerves: v.value0.nerves,
2335+ bones: new Column(v.value0.children)
2336+ }]
2337+ }, v.value1);
2338+ };
22012339
22022340 // output/Web.DOM.NonElementParentNode/foreign.js
22032341 function _getElementById(id) {
@@ -2245,34 +2383,38 @@
22452383
22462384 // output/Plum/index.js
22472385 var bind2 = /* @__PURE__ */ bind(bindEffect);
2386+ var map4 = /* @__PURE__ */ map(functorArray);
22482387 var outerStyle = "html,body{height:100%;padding:0;margin:0;}";
22492388 var run3 = function(id) {
22502389 return function(plum2) {
22512390 return function __do() {
22522391 var modelRef = bind2(plum2.init)($$new)();
22532392 var v = bind2(bind2(windowImpl)(document2))(function() {
2254− var $6 = getElementById(id);
2255− return function($7) {
2256− return $6(toNonElementParentNode($7));
2393+ var $12 = getElementById(id);
2394+ return function($13) {
2395+ return $12(toNonElementParentNode($13));
22572396 };
22582397 }())();
22592398 if (v instanceof Just) {
22602399 var projector = createProjector();
22612400 return replace(projector)(v.value0)(function __do2() {
22622401 var model = read(modelRef)();
2263− var el = grow(function(msg) {
2402+ var el = map4(grow(function(msg) {
22642403 return function __do3() {
22652404 var m = read(modelRef)();
22662405 var m_ = plum2.update(msg)(m)();
22672406 return write(m_)(modelRef)();
22682407 };
2269− })(plum2.view(model));
2408+ }))(function() {
2409+ var v1 = plum2.view(model);
2410+ return v1.value0.children;
2411+ }());
22702412 return h2("div")({
22712413 styles: {
22722414 height: "100%",
22732415 width: "100%"
22742416 }
2275− })([h2("style")({})([string(outerStyle)]), el]);
2417+ })(cons(h2("style")({})([string(outerStyle)]))(el));
22762418 })();
22772419 }
22782420 ;
@@ -2280,22 +2422,23 @@
22802422 return unit;
22812423 }
22822424 ;
2283− throw new Error("Failed pattern match at Plum (line 25, column 92 - line 39, column 25): " + [v.constructor.name]);
2425+ throw new Error("Failed pattern match at Plum (line 26, column 92 - line 42, column 25): " + [v.constructor.name]);
22842426 };
22852427 };
22862428 };
22872429
22882430 // output/Main/index.js
22892431 var pure2 = /* @__PURE__ */ pure(applicativeEffect);
2290− var map4 = /* @__PURE__ */ map(functorArray);
2432+ var discard2 = /* @__PURE__ */ discard(discardUnit)(/* @__PURE__ */ bindUIWith(monoidArray));
2433+ var mempty4 = /* @__PURE__ */ mempty(/* @__PURE__ */ monoidUIWith(monoidUnit)(monoidUnit));
22912434 var plum = {
22922435 init: /* @__PURE__ */ pure2({
22932436 text: "Test"
22942437 }),
22952438 view: function(model) {
2296− return view([])([])(new Column([view([])([])(new Link("https://iko.soy", {
2297− newTab: false
2298− }, view([])([])(new Text("my website")))), view([])([])(new Row(map4($$const(view([])([new BackgroundColor(rgb(1)(0)(0))])(new Text("hello"))))(range2(1)(100))))]));
2439+ return column(discard2(text("hi")(mempty4))(function() {
2440+ return text("hello")(mempty4);
2441+ }));
22992442 },
23002443 update: function(msg) {
23012444 return function(model) {
plum/src/Main.purs+5−8
@@ -5,7 +5,7 @@ import Prelude
55import Data.Array as Array
66import Effect (Effect)
77import Plum as Plum
8−import Plum.View (Bones(..), Meat(..), rgb, view)
8+import Plum.View
99
1010main :: Effect Unit
1111main = do
@@ -16,13 +16,10 @@ type Model = { text :: String }
1616plum :: Plum.Plum Unit Model
1717plum =
1818 { init: pure { text: "Test" }
19− , view: \model ->
20− view [] []
21− ( Column
22− [ view [] [] (Link "https://iko.soy" { newTab: false } $ view [] [] (Text "my website"))
23− , view [] [] (Row $ Array.range 1 100 # map (const $ view [] [ BackgroundColor (rgb 1.0 0.0 0.0) ] (Text "hello")))
24− ]
25− )
19+ , view: \model -> do
20+ column $ do
21+ text "hi" mempty
22+ text "hello" mempty
2623 , update: \msg model -> case msg of
2724 _ -> pure { text: "Button pressed" }
2825 }
plum/src/Plum.purs+16−10
@@ -2,12 +2,12 @@ module Plum (Plum, run) where
22
33import Prelude
44
5+import Data.Array ((:))
56import Data.Maybe (Maybe(..))
67import Effect (Effect)
78import Effect.Ref as Ref
8−import Maquette (h)
99import Maquette as Maquette
10−import Plum.View (View, grow)
10+import Plum.View (UI, UIWith(..), grow)
1111import Web.DOM.NonElementParentNode (getElementById) as Web
1212import Web.HTML (window) as Web
1313import Web.HTML.HTMLDocument (toNonElementParentNode) as Web
@@ -16,7 +16,7 @@ import Web.HTML.Window (document) as Web
1616type Plum msg model =
1717 { init :: Effect model
1818 , update :: msg -> model -> Effect model
19− , view :: model -> View msg
19+ , view :: model -> UI msg Unit
2020 }
2121
2222run :: forall msg model. String -> Plum msg model -> Effect Unit
@@ -28,14 +28,20 @@ run id plum = do
2828 Maquette.replace projector element do
2929 model <- Ref.read modelRef
3030 let
31− el = grow
32− ( \msg -> do
33− m <- Ref.read modelRef
34− m_ <- plum.update msg m
35− Ref.write m_ modelRef
31+ el = map
32+ ( grow
33+ ( \msg -> do
34+ m <- Ref.read modelRef
35+ m_ <- plum.update msg m
36+ Ref.write m_ modelRef
37+ Maquette.scheduleRender projector
38+ )
3639 )
37− (plum.view model)
38− pure $ Maquette.h "div" { styles: { height: "100%", width: "100%" } } [ Maquette.h "style" {} [ Maquette.string outerStyle ], el ]
40+ (let UI { children } _ = plum.view model in children)
41+ pure $ Maquette.h
42+ "div"
43+ { styles: { height: "100%", width: "100%" } }
44+ (Maquette.h "style" {} [ Maquette.string outerStyle ] : el)
3945 Nothing -> pure unit
4046
4147outerStyle :: String
plum/src/Plum/View.purs+143−3
@@ -13,13 +13,28 @@ module Plum.View
1313 , rgba255
1414 , rgb
1515 , rgba
16+ , UI
17+ , UIWith(..)
18+ , UIViewWith
19+ , column
20+ , row
21+ , stack
22+ , text
23+ , link
24+ , newTabLink
25+ , el
26+ , download
27+ , downloadAs
28+ , image
29+ , spacing
30+ , explain
1631 ) where
1732
1833import Prelude
1934
2035import Data.Array as Array
2136import Data.Int as Int
22−import Data.Maybe (Maybe)
37+import Data.Maybe (Maybe(..))
2338import Data.Maybe as Maybe
2439import Data.Tuple.Nested ((/\))
2540import Effect (Effect)
@@ -30,11 +45,122 @@ import Maquette as Maquette
3045import Record as Record
3146import Record.Unsafe.Union as Record
3247
48+type UIViewWith children msg = { nerves :: Array (Nerve msg), meat :: Array Meat, children :: children }
49+
50+type UIView msg = UIViewWith (Array (View msg)) msg
51+
52+data UIWith children msg a = UI (UIViewWith children msg) a
53+
54+instance (Semigroup children, Semigroup a) => Semigroup (UIWith children msg a) where
55+ append (UI v a) (UI v' a') = UI (v <> v') (a <> a')
56+
57+instance (Monoid children, Monoid a) => Monoid (UIWith children msg a) where
58+ mempty = UI mempty mempty
59+
60+type UI msg a = UIWith (Array (View msg)) msg a
61+
62+instance Functor (UIWith children msg) where
63+ map f (UI v a) = UI v $ f a
64+
65+instance Monoid children => Apply (UIWith children msg) where
66+ apply (UI views f) (UI views' a) = UI (views <> views') (f a)
67+
68+instance Monoid children => Applicative (UIWith children msg) where
69+ pure = UI mempty
70+
71+instance Monoid children => Bind (UIWith children msg) where
72+ bind (UI views a) f =
73+ let
74+ UI views' b = f a
75+ in
76+ UI (views <> views') b
77+
78+instance Monoid children => Monad (UIWith children msg)
79+
80+column :: forall msg a. UI msg a -> UI msg a
81+column (UI { nerves, meat, children } a) =
82+ UI (mempty :: UIView msg) { children = [ { meat, nerves, bones: Column children } ] } a
83+
84+row :: forall msg a. UI msg a -> UI msg a
85+row (UI { nerves, meat, children } a) =
86+ UI (mempty :: UIView msg) { children = [ { meat, nerves, bones: Row children } ] } a
87+
88+stack :: forall msg a. UI msg a -> UI msg a
89+stack (UI { nerves, meat, children } a) =
90+ UI (mempty :: UIView msg) { children = [ { meat, nerves, bones: Stack children } ] } a
91+
92+text :: forall msg. String -> UIWith Unit msg Unit -> UI msg Unit
93+text s (UI { nerves, meat } a) = UI (mempty :: UIView msg) { children = [ { meat, nerves, bones: Text s } ] } a
94+
95+link :: forall msg a. String -> UI msg a -> UI msg a
96+link url (UI { nerves, meat, children } a) = UI
97+ (mempty :: UIView msg)
98+ { children =
99+ [ { meat
100+ , nerves
101+ , bones: Link url { newTab: false } (Maybe.fromMaybe none $ Array.head children)
102+ }
103+ ]
104+ }
105+ a
106+
107+el :: forall msg a. UI msg a -> UI msg a
108+el (UI { nerves, meat, children } a) = UI
109+ (mempty :: UIView msg)
110+ { children =
111+ [ { meat
112+ , nerves
113+ , bones: Wrapper (Maybe.fromMaybe none $ Array.head children)
114+ }
115+ ]
116+ }
117+ a
118+
119+newTabLink :: forall msg a. String -> UI msg a -> UI msg a
120+newTabLink url (UI { nerves, meat, children } a) = UI
121+ (mempty :: UIView msg)
122+ { children =
123+ [ { meat
124+ , nerves
125+ , bones: Link url { newTab: true } (Maybe.fromMaybe none $ Array.head children)
126+ }
127+ ]
128+ }
129+ a
130+
131+download :: forall msg a. String -> UI msg a -> UI msg a
132+download url (UI { nerves, meat, children } a) = UI
133+ (mempty :: UIView msg)
134+ { children =
135+ [ { meat
136+ , nerves
137+ , bones: Download url { filename: Nothing } (Maybe.fromMaybe none $ Array.head children)
138+ }
139+ ]
140+ }
141+ a
142+
143+downloadAs :: forall msg a. String -> { filename :: String } -> UI msg a -> UI msg a
144+downloadAs url { filename } (UI { nerves, meat, children } a) = UI
145+ (mempty :: UIView msg)
146+ { children =
147+ [ { meat
148+ , nerves
149+ , bones: Download url { filename: Just filename } (Maybe.fromMaybe none $ Array.head children)
150+ }
151+ ]
152+ }
153+ a
154+
155+image :: forall msg a. String -> { description :: String } -> UIWith Unit msg a -> UI msg a
156+image url description (UI { nerves, meat } a) =
157+ UI (mempty :: UIView msg) { children = [ { meat, nerves, bones: Image url description } ] } a
158+
33159h :: String -> Skin -> Array VNode -> VNode
34−h el (Skin styles) children = Maquette.h el { styles } children
160+h elem (Skin styles) children = Maquette.h elem { styles } children
35161
36162hWith :: forall props. String -> Record props -> Skin -> Array VNode -> VNode
37−hWith el props (Skin styles) children = Maquette.h el (Record.unsafeUnion props { styles }) children
163+hWith elem props (Skin styles) children = Maquette.h elem (Record.unsafeUnion props { styles }) children
38164
39165data Length = Px Int | Fill | Fit | Max Int Length | Min Int Length
40166
@@ -42,6 +168,15 @@ data Alignment = Start | Center | End
42168
43169data Direction = X | Y
44170
171+meat :: forall ch msg a. Monoid ch => Monoid a => Meat -> UIWith ch msg a
172+meat m = UI (mempty :: UIViewWith ch msg) { meat = [ m ] } mempty
173+
174+spacing :: forall ch msg a. Monoid ch => Monoid a => { x :: Int, y :: Int } -> UIWith ch msg a
175+spacing { x, y } = meat $ Spacing x y
176+
177+explain :: forall ch msg a. Monoid ch => Monoid a => UIWith ch msg a
178+explain = meat Explain
179+
45180data Meat
46181 = Spacing Int Int
47182 | Explain
@@ -61,6 +196,9 @@ data Nerve msg = OnClick msg
61196
62197type View msg = { nerves :: Array (Nerve msg), meat :: Array Meat, bones :: Bones msg }
63198
199+none :: forall msg. View msg
200+none = { nerves: [], meat: [], bones: None }
201+
64202view :: forall msg. Array (Nerve msg) -> Array Meat -> Bones msg -> View msg
65203view nerves meat bones = { nerves, meat, bones }
66204
@@ -162,6 +300,7 @@ data Bones msg
162300 | Link String { newTab :: Boolean } (View msg)
163301 | Download String { filename :: Maybe String } (View msg)
164302 | Image String { description :: String }
303+ | None
165304
166305newtype Mutation = Mutation { extraSkin :: Skin }
167306
@@ -215,6 +354,7 @@ growSkin fire (Mutation mutation) { meat, bones } =
215354 (skn (Flexbox X) <> sk "display" "flex" <> sk "flex-direction" "row")
216355 [ growSkin fire mempty child ]
217356 Image src { description } -> hWith "img" { src, alt: description } (skn Generic) []
357+ None -> h "div" mempty []
218358
219359grow :: forall msg. (msg -> Effect Unit) -> View msg -> VNode
220360grow fire v = growSkin fire mempty v