[Functional Programming] Function modelling -- 7. contramap & Endo execrises
Posted answer1215
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Functional Programming] Function modelling -- 7. contramap & Endo execrises相关的知识,希望对你有一定的参考价值。
// Definition const Endo = run => ({ run, concat: other => Endo(x => other.run(run(x))) }); Endo.empty = () => Endo(x => x); // Ex1: // ========================= const classToClassName = html => html.replace(/class=/gi, "className="); const updateStyleTag = html => html.replace(/style="(.*)"/gi, "style={{$1}}"); const htmlFor = html => html.replace(/for=/gi, "htmlFor="); //const ex1 = html => // htmlFor(updateStyleTag(classToClassName(html))) //rewrite using Endo // Can also use List foldMap // Solution1 // const ex1 = html => List.of(htmlFor, updateStyleTag, classToClassName).foldMap(Endo, Endo.empty()).run(html) // Solution 2 // const ex2 = html => [htmlFor, updateStyleTag, classToClassName].reduce((acc, curr) => acc.concat(Endo(curr)), Endo.empty()).run(html) // Solution 3 const ex1 = html => Endo(htmlFor) .concat(Endo(updateStyleTag)) .concat(Endo(classToClassName)) .run(html); QUnit.test("Ex1", assert => { const template = ` <div class="awesome" style="border: 1px solid red"> <label for="name">Enter your name: </label> <input type="text" id="name" /> </div> `; const expected = ` <div className="awesome" style={{border: 1px solid red}}> <label htmlFor="name">Enter your name: </label> <input type="text" id="name" /> </div> `; assert.deepEqual(expected, ex1(template)); }); // Ex2: model a predicate function :: a -> Bool and give it contramap() and concat(). i.e. make the test work // ========================= const Pred = run => ({ run, contramap(f) { return Pred(x => run(f(x))); }, concat(otherM) { return Pred(x => run(x) && otherM.run(x)); } }); // todo QUnit.test("Ex2: pred", assert => { const p = Pred(x => x > 4) .contramap(x => x.length) .concat(Pred(x => x.startsWith("s"))); const result = ["scary", "sally", "sipped", "the", "soup"].filter(p.run); assert.deepEqual(result, ["scary", "sally", "sipped"]); }); // Ex3: // ========================= const extension = file => file.name.split(".")[1]; const matchesAny = regex => str => str.match(new RegExp(regex, "ig")); const matchesAnyP = pattern => Pred(matchesAny(pattern)); // Pred(str => Bool) // TODO: rewrite using matchesAnyP. Take advantage of contramap and concat //const ex3 = file => // matchesAny(‘txt|md‘)(extension(file)) && matchesAny(‘functional‘)(file.contents) const ex3 = file => matchesAnyP("txt|md") .contramap(extension) .concat(matchesAnyP("functional").contramap(f => f.contents)) .run(file); QUnit.test("Ex3", assert => { const files = [ { name: "blah.dll", contents: "2|38lx8d7ap1,3rjasd8uwenDzvlxcvkc" }, { name: "intro.txt", contents: "Welcome to the functional programming class" }, { name: "lesson.md", contents: "We will learn about monoids!" }, { name: "outro.txt", contents: "Functional programming is a passing fad which you can safely ignore" } ]; assert.deepEqual([files[1], files[3]], files.filter(ex3)); });
以上是关于[Functional Programming] Function modelling -- 7. contramap & Endo execrises的主要内容,如果未能解决你的问题,请参考以下文章
[Functional Programming ADT] Debug a Functional JavaScript composeK Flow