码迷,mamicode.com
首页 > 其他好文 > 详细

[Functional Programming] Function modelling -- 7. contramap & Endo execrises

时间:2020-03-15 22:00:48      阅读:53      评论:0      收藏:0      [点我收藏+]

标签:split   sipp   ignore   ini   reg   map   oid   lis   dma   

// 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

标签:split   sipp   ignore   ini   reg   map   oid   lis   dma   

原文地址:https://www.cnblogs.com/Answer1215/p/12500068.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!