• [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));
    });
  • 相关阅读:
    五分钟完成 ABP vNext 通讯录 App 开发
    .NET Conf: Xamarin专场会议3.23 开幕
    2020 年 中国.NET开发者调查报告
    推荐一个很棒的开源工作流elsa-core
    尝试使用 Visual Studio Online (Cloud IDE)
    Mongo2Go 介绍
    DevExpress作为企业赞助商加入.NET基金会
    【新书推荐】《ASP.NET Core微服务实战:在云环境中开发、测试和部署跨平台服务》 带你走近微服务开发
    云原生时代 来看看十年前李彦宏、马化腾和马云对云计算的评价
    .NET 在云原生时代的蜕变,让我在云时代脱颖而出
  • 原文地址:https://www.cnblogs.com/Answer1215/p/12500068.html
Copyright © 2020-2023  润新知