Upgrade to Pro — share decks privately, control downloads, hide ads and more …

JavaScript ( 時々 TypeScript ) で ゆるやかにはじめる関数型プログラミング

JavaScript ( 時々 TypeScript ) で ゆるやかにはじめる関数型プログラミング

初夏のJavaScript祭 2018 での登壇時に発表した資料です。
https://javascript-fes.doorkeeper.jp/events/73314
#jsfes

wakamsha

May 19, 2018
Tweet

More Decks by wakamsha

Other Decks in Technology

Transcript

  1. +BWB4DSJQU ࣌ʑ5ZQF4DSJQU
    Ͱ
    ΏΔ΍͔ʹ͸͡ΊΔؔ਺ܕϓϩάϥϛϯά
    Introducing functional programming w/ JavaScript
    ( & sometimes TypeScript )
    ॳՆͷ+BWB4DSJQUࡇ

    !XBLBNTIB
    /BPLJ:"."%"

    View Slide

  2. ͸͡Ίʹ
    +BWB4DSJQUʹ͸ؔ਺ܕϓϩάϥϛϯάͷΤοηϯε͕ଟ෼ʹؚ·Ε͍ͯΔ
    ϦΞΫςΟϒɾϓϩάϥϛϯάͷྲྀߦʹΑΓɺXFCϑϩϯτΤϯυͷੈք
    ʹ΋ਁಁ͖ͯͨ͠
    ͦΜͳؔ਺ܕϓϩάϥϛϯάͷ͞ΘΓ෦෼Λ͝঺հ

    View Slide

  3. ·ͣ͸ͪ͜ΒͷίʔυΛޚཡ͍ͩ͘͞
    First, please take a look at this code…
    TS

    View Slide

  4. ['foo', 'bar', 'baz'].map((val: string) => {
    return `${val}!!!`;
    });
    //=> ['foo!!!', 'bar!!!', 'baz!!!']
    function double(x: number): number {
    return x * 2;
    }
    double(3); //=> 6

    View Slide

  5. ['foo', 'bar', 'baz'].map((val: string) => {
    return `${val}!!!`;
    });
    //=> ['foo!!!', 'bar!!!', 'baz!!!']
    function double(x: number): number {
    return x * 2;
    }
    double(3); //=> 6
    ͲͪΒ΋ؔ਺ܕϓϩάϥϛϯάͷఆٛʹଈͨ͠΋ͷͰ͢

    View Slide

  6. ['foo', 'bar', 'baz'].map((val: string) => {
    return `${val}!!!`;
    });
    //=> ['foo!!!', 'bar!!!', 'baz!!!']
    function double(x: number): number {
    return x * 2;
    }
    double(3); //=> 6
    ͦ΋ͦ΋ؔ਺ܕϓϩάϥϛϯάͱ͸ʁ
    ෳ਺ͷࣜΛؔ਺ͷద༻ʹΑͬͯ૊Έ߹ΘͤΔϓϩάϥϛϯάελΠϧ
    ؔ਺߹੒
    ෭࡞༻ͷແ͍ؔ਺ΛϝΠϯʹѻ͏ϓϩάϥϛϯάελΠϧ
    ७ਮ

    View Slide

  7. ['foo', 'bar', 'baz'].map((val: string) => {
    return `${val}!!!`;
    });
    //=> ['foo!!!', 'bar!!!', 'baz!!!']
    function double(x: number): number {
    return x * 2;
    }
    double(3); //=> 6
    ରٛʹҐஔ͢Δͷ͕ʰखଓ͖ܕϓϩάϥϛϯάʱ
    ม਺Λഁյతʹॻ͖׵͑ΔͳͲɺ෭࡞༻Λۦ࢖͢Δ
    ໨తͷͨΊʹ࣮ߦ͢΂͖Ұ࿈ͷεςοϓΛҰͭͷؔ਺ʹ࣋ͨͤΔ
    ఆٛͨؔ͠਺͸ϓϩάϥϜ࣮ߦதͷ೚ҙͷλΠϛϯάͰݺͼग़ͤΔ

    View Slide

  8. ؔ਺߹੒
    খ͞ͳؔ਺Λ૊Έ߹ΘͤΔͱ͍͏͜ͱ
    ߴ֊ؔ਺
    ७ਮ
    ෭࡞༻Λແ͘͢ͱ͍͏͜ͱ
    ෆมੑ *NNVUBCMF

    ࢀরಁաੑ
    ͜Ε͔Βؔ਺ܕϓϩάϥϛϯάΛֶͿਓ΁
    ຊ೔͓࣋ͪؼΓ͍͖͍ͨͩͨ͜ͱ
    1PJOUTUP
    MFBSO

    View Slide

  9. ؔ਺߹੒
    ෳ਺ͷࣜΛؔ਺ͷద༻ʹΑͬͯ૊Έ߹ΘͤΔϓϩάϥϛϯάελΠϧ

    View Slide

  10. ͱɺͦͷલʹߴ֊ؔ਺ʹ͍ͭͯ
    About a higher-order function

    View Slide

  11. ͱɺͦͷલʹߴ֊ؔ਺ʹ͍ͭͯ
    [1, 4, 9, 16].map(x => x * 2);
    ['spray', 'limit', 'exuberant', 'present'].filter(word =>
    word.length > 6
    );
    "SSBZͷ*UFSBUJWFͳϝιου͸ؔ਺ΛҾ਺ʹऔΔ
    ؔ਺ΛҾ਺PS໭Γ஋ͱͯ͠ѻ͏΋ͷΛʰߴ֊ؔ਺ʱͱ͍͏
    ߴ֊ؔ਺͸ؔ਺Λ߹੒͢Δ΋ͷͰ͋Δ

    View Slide

  12. ؆୯ͳؔ਺߹੒Λ΍ͬͯΈΑ͏
    Basic Examples

    View Slide

  13. /**
    * ཁ݅: ͋Δ਺஋ʹ 1 Λ଍ͯ͠ 2ഒͨ݁͠ՌΛฦ͢ػೳ
    */
    // Ұͭͷؔ਺Ͱ࣮ݱ͢Δͱ͜͏ͳΔ
    // ಛԽ͗ͯͯ͢͠൚༻ੑʹ͚ܽΔͨΊɺอकੑ΋௿͍
    function addOneTimesTwo(x: number): number {
    return (x + 1) * 2;
    }
    // Ҿ਺ʹ 1 Λ଍͚ͩ͢
    function addOne(x: number): number {
    return x + 1;
    }
    // Ҿ਺Λ 2ഒ͢Δ͚ͩ
    function timesTwo(x: number): number {
    return x * 2;
    }

    View Slide

  14. /**
    * ཁ݅: ͋Δ਺஋ʹ 1 Λ଍ͯ͠ 2ഒͨ݁͠ՌΛฦ͢ػೳ
    */
    // ݁Ռ͸શͯಉ͡
    addOneTimesTwo(2); //=> 6
    const x = addOne(2);
    timesTwo(x); //=> 6
    timesTwo(addOne(2)); //=> 6

    View Slide

  15. DPNQPTF߹੒༻ͷؔ਺Λ࡞ͬͯΈΑ͏
    Basic Examples

    View Slide

  16. function compose(fn1, fn2) {
    return function(x0) {
    return fn1(fn2(x0));
    }
    }
    // TypeScript Ͱॻ͘ͱ͜Μͳײ͡
    function compose(
    fn1: (x: T1) => T2,
    fn2: (x0: V0) => T1,
    ): (x0: V0) => T2 {
    return function(x0: V0): T2 {
    return fn1(fn2(x0));
    };
    }

    View Slide

  17. const addOneTimesTwo = compose(timesTwo, addOne);
    addOneTimesTwo(2);
    //=> 6
    compose(timesTwo, addOne)(2);
    //=> 6

    View Slide

  18. const addOneTimesTwo = compose(timesTwo, addOne);
    addOneTimesTwo(2);
    //=> 6
    compose(timesTwo, addOne)(2);
    //=> 6
    ؔ਺߹੒
    ؔ਺͸ͻͱ·ͱ·Γʹͤͣɺࡉ͔͘෼ղ͢Δ
    খ͞ͳؔ਺Λ૊Έ߹Θͤͯେ͖ͳػೳΛ࣮ݱ͢Δ
    খ͘͞୯७ͳؔ਺͸ɺͦΕ͚ͩ൚༻ੑ͕ߴ͍
    6OJU5FTUΛॻ͘ͷ͕༰қʹͳΔ

    View Slide

  19. ७ਮ
    ෭࡞༻ͷͳ͍ؔ਺ΛϝΠϯʹѻ͏ϓϩάϥϛϯάελΠϧ

    View Slide

  20. ·ͣ͸ͪ͜ΒͷίʔυΛޚཡ͍ͩ͘͞
    First, please take a look at this code…

    View Slide

  21. // 1
    function sum(x: number, y: number): number {
    return x + y;
    }
    // 2
    let i: number = 0;
    function sum2(x: number, y: number): number {
    i += x + y;
    return x + y;
    }
    // 3
    function sum3(x: number, y: number): number {
    return x + y + i;
    }
    // 4
    function sum4(x: number, y: number): number {
    const result = x + y;
    console.log(result);
    return result;
    }

    View Slide

  22. // 1
    function sum(x: number, y: number): number {
    return x + y;
    }
    // 2
    let i: number = 0;
    function sum2(x: number, y: number): number {
    i += x + y;
    return x + y;
    }
    // 3
    function sum3(x: number, y: number): number {
    return x + y + i;
    }
    // 4
    function sum4(x: number, y: number): number {
    const result = x + y;
    console.log(result);
    return result;
    }
    Ұͭ໨͚͕ͩ७ਮͳؔ਺Ͱ͢
    ଞ͸શͯʰෆ७ʱͳؔ਺Ͱ͢

    View Slide

  23. // 1
    function sum(x: number, y: number): number {
    return x + y;
    }
    // 2
    let i: number = 0;
    function sum2(x: number, y: number): number {
    i += x + y;
    return x + y;
    }
    // 3
    function sum3(x: number, y: number): number {
    return x + y + i;
    }
    // 4
    function sum4(x: number, y: number): number {
    const result = x + y;
    console.log(result);
    return result;
    }
    ७ਮͳؔ਺ͱ͸
    ໭Γ஋͸ඞͣҾ਺ͱͯ͠༩͑ΒΕͨ஋͔ΒͷΈܭࢉ͞ΕΔ
    ؔ਺ͷ֎෦Ͱมߋ͞ΕΔՄೳੑͷ͋ΔσʔλʹҰ੾ґଘ͠ͳ͍
    ؔ਺࣮ߦ෦ͷ֎ଆʹଘࡏ͢ΔԿ͔͠Βͷঢ়ଶΛҰ੾มߋ͠ͳ͍

    View Slide

  24. // Ҿ਺ͷ஋Λ଍͠ࢉ͚ͨͩ͠ ( ७ਮ )
    function sum(x: number, y: number): number {
    return x + y;
    }
    // άϩʔόϧม਺Λมߋ͍ͯ͠Δ
    let i: number = 0;
    function sum2(x: number, y: number): number {
    i += x + y;
    return x + y;
    }
    // ໭Γ஋͕Ҿ਺͚ͩ͡Όͳ͘άϩʔόϧม਺ʹґଘͯ͠Δ
    function sum3(x: number, y: number): number {
    return x + y + i;
    }
    // console.log ͱ͍͏׬શʹ֎ͷੈքʹׯবͯ͠Δ
    function sum4(x: number, y: number): number {
    const result = x + y;
    console.log(result);
    return result;
    }

    View Slide

  25. ෭࡞༻͸ͳΔ΂͘ແ͍ํ͕๬·͍͠
    ঢ়ଶΛؔͨ͠ґଘؔ܎͕ੜ·Εͯ͠·͏
    ঢ়ଶͱ͸άϩʔόϧม਺΍ΠϯελϯεͳͲ
    ґଘؔ܎ͱ͸ؔ਺ͷݺͼग़͠ॱংͳͲ
    ࠶ݱੑʹ੍໿͕ൃੜ͢Δ

    View Slide

  26. ෭࡞༻Λແͨ͘͢ΊͷୈҰา
    The first step to eliminate side effects…

    View Slide

  27. ෭࡞༻Λແͨ͘͢ΊͷୈҰา
    let i: number = 0;
    function sum3(x: number, y: number, i: number): number {
    return x + y + i;
    }
    ॲཧʹඞཁͳσʔλ͸શͯҾ਺ͱͯ͠ड͚औΔ
    άϩʔόϧม਺΋Ҿ਺ͱͯ͠ड͚औΕ͹0,

    View Slide

  28. interface User {
    firstName: string;
    lastName: string;
    greet(): string;
    }

    View Slide

  29. class User {
    constructor(private firstName: string, private lastName: string) {}
    public updateFirstName(name: string): User {
    return new User(name, this.lastName);
    }
    public updateLastName(name: string): User {
    return new User(this.firstName, name);
    }
    public greet(): string {
    return `hello, ${this.firstName} ${this.lastName}!!`;
    }
    }

    View Slide

  30. class User {
    constructor(private firstName: string, private lastName: string) {}
    public updateFirstName(name: string): User {
    return new User(name, this.lastName);
    }
    public updateLastName(name: string): User {
    return new User(this.firstName, name);
    }
    public greet(): string {
    return `hello, ${this.firstName} ${this.lastName}!!`;
    }
    }
    ΦϒδΣΫτ͸$MBTTͱͯ͠ఆٛ͢Δ
    ֤ϝιουͷ࠷ޙʹࣗ਎ͷ৽͍͠ΠϯελϯεΛ໭Γ஋ʹฦ͢
    ຖճ৽͍͠ΠϯελϯεΛͦͷ࣌ͷ಺෦஋͔Βੜ੒͢Δ
    ݺͼग़͠ͷίϯϑϦΫτ͕ൃੜ͠ͳ͍

    View Slide

  31. ࢀরಁաੑ
    ؔ਺Λͦͷ໭Γ஋ࣗମʹࠩ͠ସ͑ͯ΋ϓϩάϥϜશମ͕յΕͳ͍͜ͱ
    ೔ຊͷࠃձ͸೔ຊͷट౎Ͱ։͔ΕΔ
    ೔ຊͷࠃձ͸౦ژͰ։͔ΕΔ

    View Slide

  32. ७ਮ
    ґଘؔ܎Λ࣋ͨͳ͍ͱ͍͏͜ͱ͸ɺͦΕ͚ͩίʔυͷݟ௨͕͠ྑ͍
    ݟ௨͠ͷྑ͍ίʔυ͸อकੑ͕ߴ͍
    ґଘؔ܎Λ࣋ͨͳ͍७ਮؔ਺͸6OJU5FTU͕͠΍͍͢
    6OJU5FTUͷ͠΍͍͢ίʔυ͸อकੑ͕ߴ͍
    ७ਮؔ਺͸߹੒͕͠΍͍͢

    View Slide

  33. 3BNEBKT
    ௒ڧྗͳؔ਺ܕϓϩάϥϛϯά༻ JavaScript ϥΠϒϥϦ

    View Slide

  34. 3BNEBKT
    ίϨΫγϣϯૢ࡞ܥͱෆมੑ୲อ ७ਮ
    ͷೋ໘ੑΛซͤ࣋ͭ
    ΄΅શͯͷ"1*͸ෆมੑͱ෭࡞༻ͷͳ͍ػೳ *NNVUBCMF
    ͱͯ͠ઃܭ
    "1*໊͕)BTLFMM΍4DBMBͷͦΕʹΠϯεύΠΞ͞Ε໋໊ͨ

    View Slide

  35. PSYENCE:MEDIA
    PRODUCED BY
    ৄ͘͠͸ฐࣾϒϩάΛ͝ࢀর͍ͩ͘͞

    View Slide

  36. ؔ਺ܕϓϩάϥϛϯάͷϝϦοτσϝϦοτ
    First, please take a look at this code…
    TS

    View Slide

  37. ؔ਺ܕϓϩάϥϛϯάͷϝϦοτ
    ҰͭҰͭͷ෦඼ ؔ਺
    ͕খ͍͞ͷͰอकੑɾ֦ுੑ͕ߴ͍
    6OJU5FTU͕ॻ͖΍͍͢
    ґଘؔ܎Ͱ಄Λ೰·͢͜ͱ͕গͳ͍
    ෭࡞༻Λ௥͍ग़͢͜ͱͰ༧ظͤ͵ಈ࡞ ෆ۩߹
    Λະવʹ๷͛Δ
    TS

    View Slide

  38. ؔ਺ܕϓϩάϥϛϯάͷϝϦοτ
    Ұൠతͳ(6*ΞϓϦέʔγϣϯͱͷ૬ੑ͕ྑ͍
    ϦΞΫςΟϒϓϩάϥϛϯά 3Y΍'MVYͳͲ
    ͕ద͍ͯ͠Δ
    TS

    View Slide

  39. ؔ਺ܕϓϩάϥϛϯάͷσϝϦοτ
    ෋߽ϓϩάϥϛϯάʹͳΓ͕ͪ
    ඞવతʹؔ਺ͷݺͼग़͠ճ਺͕૿͑Δ ؔ਺߹੒ͳͲ

    ֶशίετ͕ߴ͍
    खଓ͖ܕͱ͸ύϥμΠϜ͕ͥΜͥ̽ҧ͏
    TS

    View Slide

  40. ͜Ε͔Βؔ਺ܕϓϩάϥϛϯάΛֶͿਓ΁

    View Slide

  41. ͜Ε͔Βؔ਺ܕϓϩάϥϛϯάΛֶͿਓ΁

    View Slide

  42. ͜Ε͔Βؔ਺ܕϓϩάϥϛϯάΛֶͿਓ΁
    ʰ1BSTFSΛ࡞ͬͯΈΔʱ͕୊ࡐͱ͓ͯ͢͢͠Ί
    ద౰ͳ+40/σʔλΛߏ଄ղੳͯ͠ΈΔͱ͔
    ؆୯ͳίʔυϑΥʔϚολΛ࡞ͬͯΈΔͱ͔

    View Slide

  43. ͜Ε͔Βؔ਺ܕϓϩάϥϛϯάΛֶͿਓ΁
    ຊ֨తʹֶͼ͍ͨͳΒ)BTLFMM
    ਖ਼ਅਖ਼໏ͷʰ७ਮؔ਺ܕϓϩάϥϛϯάݴޠʱ
    ੩తܕ෇͚ݴޠ
    XFCܥͷۀ຿ʹ௚݁͢Δ͜ͱ͸গͳ͍͕ɺʰڭཆʱͱͯ͠
    ֶͿͳΒ͜Ε͕࠷ద
    ʰ͍͢͝)ຊʱҰ࡭ࣸܦ͢Δ͚ͩͰ΋͔ͳΓͷֶͼʹͳΔ

    View Slide

  44. *OUSPEVDFNZTFMG
    Զͷ໊ΛݴͬͯΈΖ
    ࣗݾ঺հ

    View Slide

  45. !XBLBNTIB
    *OUSPEVDFNZTFMG
    /BPLJ:"."%"ࢁా௚थ
    XFCϑϩϯτΤϯυΤϯδχΞ
    ॴଐגࣜձࣾϦΫϧʔτϚʔέςΟϯάύʔτφʔζ
    ෭ۀۀ຿ҕୗͱͯ͠๭ελʔτΞοϓاۀΛ͓ख఻͍த

    View Slide

  46. PSYENCE:MEDIA
    PRODUCED BY

    View Slide

  47. PSYENCE:MEDIA
    PRODUCED BY
    ϦΫϧʔτϚʔέςΟϯάύʔτφʔζͷެࣜςοΫϒϩά
    ٕज़ྗɾϊ΢ϋ΢ͷମܥԽ
    3.1ͷ಺੡։ൃ૊৫͓Αͼࣥචऀͷࣾ֎ϓϨθϯε޲্
    ࠾༻ϒϥϯσΟϯάڧԽ
    ۀք׆ੑԽ΁ͷߩݙ
    14:&/$&.&%*"

    View Slide

  48. View Slide

  49. https://tech.recruit-mp.co.jp
    3.1 ϒϩά

    View Slide

  50. 5IBOLZPV

    View Slide