zoukankan      html  css  js  c++  java
  • [Functional Programming] Working with two functors(Applicative Functors)-- Part2 --liftAN

    Let's examine a pointfree way to write these applicative calls. Since we know map is equal to of/ap, we can write generic functions that will ap as many times as we specify:

    const liftA2 = curry((g, f1, f2) => f1.map(g).ap(f2));
    
    const liftA3 = curry((g, f1, f2, f3) => f1.map(g).ap(f2).ap(f3));
    
    // liftA4, etc

    Let's see the previous examples written this way:

    const profile = name => email => `${name}__${email}`;
    const safeProfile = liftA2(profile);
    const res1 = safeProfile(prop('name', user), prop('email', user)); // John Doe__blurp_blurp
    liftA2(add, Maybe.of(2), Maybe.of(3));
    // Maybe(5)
    
    liftA2(renderPage, Http.get('/destinations'), Http.get('/events'));
    // Task('<div>some page with dest and events</div>')
    
    liftA3(signIn, getVal('#email'), getVal('#password'), IO.of(false));
    // IO({ id: 3, email: 'gg@allin.com' })

    liftAN: Lift a curry function into a Functor context, which will be define later;  

    liftA2(add, Maybe.of(2), Maybe.of(3)); Maybe will be the Functor context for 'add' function which has been lifted

    Laws:

    Identity

    // identity
    A.of(id).ap(v) === v;

    For example:

    const v = Identity.of('Pillow Pets');
    Identity.of(id).ap(v) === v;

    Homomorphism

    // homomorphism
    A.of(f).ap(A.of(x)) === A.of(f(x));

    homomorphism is just a structure preserving map. In fact, a functor is just a homomorphism between categories as it preserves the original category's structure under the mapping.

    A quick example:

    Either.of(toUpperCase).ap(Either.of('oreos')) === Either.of(toUpperCase('oreos'));

    Interchange

    The interchange law states that it doesn't matter if we choose to lift our function into the left or right side of ap.

    // interchange
    v.ap(A.of(x)) === A.of(f => f(x)).ap(v);

    Here is an example:

    const v = Task.of(reverse);
    const x = 'Sparklehorse';
    
    v.ap(Task.of(x)) === Task.of(f => f(x)).ap(v);

    Composition

    // composition
    A.of(compose).ap(u).ap(v).ap(w) === u.ap(v.ap(w));
    const u = IO.of(toUpperCase);
    const v = IO.of(concat('& beyond'));
    const w = IO.of('blood bath ');
    
    IO.of(compose).ap(u).ap(v).ap(w) === u.ap(v.ap(w));

    Examples:

    const safeAdd = curry((a, b) => Maybe.of(add).ap(a).ap(b));
    const safeAdd = liftA2(add);
    
    const localStorage = {  
      player1: { id:1, name: 'Albert' },  
      player2: { id:2, name: 'Theresa' },  
    };  
    
    // getFromCache :: String -> IO User  
    const getFromCache = x => new IO(() => localStorage[x]);  
    
    // game :: User -> User -> String  
    const game = curry((p1, p2) => `${p1.name} vs ${p2.name}`);
    // startGame :: IO String
    const startGame = liftA2(game, getFromCache('player1'), getFromCache('player2'));
  • 相关阅读:
    数据绑定表达式语法(Eval,Bind区别)
    使用博客园的第一件事 自定义主题
    sql2000 跨服务器复制表数据
    使用UpdatePanel 局部刷新出现中文乱码的解决方法!!
    MMC不能打开文件MSC文件
    sql 日期 、时间相关
    loaded AS2 swf call function in AS3 holder
    Rewrite the master page form action attribute in asp.net 2.0
    100万个不重复的8位的随机数
    flash 中实现斜切变型
  • 原文地址:https://www.cnblogs.com/Answer1215/p/10441240.html
Copyright © 2011-2022 走看看