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:"."%"
  2. ['foo', 'bar', 'baz'].map((val: string) => { return `${val}!!!`; }); //=>

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

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

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

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

     ෆมੑ *NNVUBCMF   ࢀরಁաੑ  ͜Ε͔Βؔ਺ܕϓϩάϥϛϯάΛֶͿਓ΁ ຊ೔͓࣋ͪؼΓ͍͖͍ͨͩͨ͜ͱ 1PJOUTUP MFBSO
  7. ͱɺͦͷલʹߴ֊ؔ਺ʹ͍ͭͯ [1, 4, 9, 16].map(x => x * 2); ['spray',

    'limit', 'exuberant', 'present'].filter(word => word.length > 6 ); "SSBZͷ*UFSBUJWFͳϝιου͸ؔ਺ΛҾ਺ʹऔΔ ؔ਺ΛҾ਺PS໭Γ஋ͱͯ͠ѻ͏΋ͷΛʰߴ֊ؔ਺ʱͱ͍͏ ߴ֊ؔ਺͸ؔ਺Λ߹੒͢Δ΋ͷͰ͋Δ
  8. /** * ཁ݅: ͋Δ਺஋ʹ 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; }
  9. /** * ཁ݅: ͋Δ਺஋ʹ 1 Λ଍ͯ͠ 2ഒͨ݁͠ՌΛฦ͢ػೳ */ // ݁Ռ͸શͯಉ͡

    addOneTimesTwo(2); //=> 6 const x = addOne(2); timesTwo(x); //=> 6 timesTwo(addOne(2)); //=> 6
  10. function compose(fn1, fn2) { return function(x0) { return fn1(fn2(x0)); }

    } // TypeScript Ͱॻ͘ͱ͜Μͳײ͡ function compose<V0, T1, T2>( fn1: (x: T1) => T2, fn2: (x0: V0) => T1, ): (x0: V0) => T2 { return function(x0: V0): T2 { return fn1(fn2(x0)); }; }
  11. const addOneTimesTwo = compose<number, number, number>(timesTwo, addOne); addOneTimesTwo(2); //=> 6

    compose<number, number, number>(timesTwo, addOne)(2); //=> 6 ؔ਺߹੒ ؔ਺͸ͻͱ·ͱ·Γʹͤͣɺࡉ͔͘෼ղ͢Δ খ͞ͳؔ਺Λ૊Έ߹Θͤͯେ͖ͳػೳΛ࣮ݱ͢Δ খ͘͞୯७ͳؔ਺͸ɺͦΕ͚ͩ൚༻ੑ͕ߴ͍ 6OJU5FTUΛॻ͘ͷ͕༰қʹͳΔ
  12. // 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; }
  13. // 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; } Ұͭ໨͚͕ͩ७ਮͳؔ਺Ͱ͢ ଞ͸શͯʰෆ७ʱͳؔ਺Ͱ͢
  14. // 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; } ७ਮͳؔ਺ͱ͸ ໭Γ஋͸ඞͣҾ਺ͱͯ͠༩͑ΒΕͨ஋͔ΒͷΈܭࢉ͞ΕΔ ؔ਺ͷ֎෦Ͱมߋ͞ΕΔՄೳੑͷ͋ΔσʔλʹҰ੾ґଘ͠ͳ͍ ؔ਺࣮ߦ෦ͷ֎ଆʹଘࡏ͢ΔԿ͔͠Βͷঢ়ଶΛҰ੾มߋ͠ͳ͍
  15. // Ҿ਺ͷ஋Λ଍͠ࢉ͚ͨͩ͠ ( ७ਮ ) 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; }
  16. ෭࡞༻Λແͨ͘͢ΊͷୈҰา let i: number = 0; function sum3(x: number, y:

    number, i: number): number { return x + y + i; } ॲཧʹඞཁͳσʔλ͸શͯҾ਺ͱͯ͠ड͚औΔ άϩʔόϧม਺΋Ҿ਺ͱͯ͠ड͚औΕ͹0,
  17. 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}!!`; } }
  18. 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ͱͯ͠ఆٛ͢Δ ֤ϝιουͷ࠷ޙʹࣗ਎ͷ৽͍͠ΠϯελϯεΛ໭Γ஋ʹฦ͢ ຖճ৽͍͠ΠϯελϯεΛͦͷ࣌ͷ಺෦஋͔Βੜ੒͢Δ ݺͼग़͠ͷίϯϑϦΫτ͕ൃੜ͠ͳ͍