[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));
});
复制代码

 

posted @   Zhentiw  阅读(210)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
历史上的今天:
2019-03-15 [Algorithm] Meeting hour optimization (Kanpsack problem) and Dynamic programming
2016-03-15 [RxJS] Toggle A Stream On And Off With RxJS
2016-03-15 [RxJS] Error Handling in RxJS
2015-03-15 [Whole Web] [Node.js] [Browserify] [Grunt] Automation task with grunt-browserify & grunt-contrib-watch
2015-03-15 [Whole Web] [Node.js] Using npm run to launch local scripts
点击右上角即可分享
微信分享提示