Slide 1

Slide 1 text

5ZQF4DSJQUͱؔ਺ܕϓϩάϥϛϯά גࣜձࣾ Ұٳ ҏ౻ ௚໵

Slide 2

Slide 2 text

ઌʹ૯࿦ • ؔ਺ܕϓϩάϥϛϯάͷΤοηϯεΛऔΓೖΕΔ͜ͱͰΑΓྑ͍ϓϩάϥϛϯά͕Ͱ͖Δݴޠ – 3FBDUͳͲ͕ྑ͍ྫ – ߴػೳͳܕγεςϜɺؔ਺Ϧςϥϧɺߴ֊ؔ਺ɺΫϩʔδϟɺNBQSFEVDFɺ෼ׂ୅ೖͳͲͷγϯλοΫεαϙʔτ – ୅਺తσʔλܕ΋ΤϛϡϨʔτ͸Ͱ͖Δ • )BTLFMM΍ 4DBMBͷΑ͏ͳؔ਺ܕϓϩάϥϛϯάݴޠʹൺֱ͢Δͱػೳ͸ෆ଍͍ͯ͠Δ – ͦΕ͕ࠓޙɺվྑ͞Ε͍ͯ͘ϩʔυϚοϓ͸ߟ͑ʹ͍͘ • ྫ֎΍ΤϥʔΛؚΉ෭࡞༻ΛͲ͏ѻ͏͔ɺӬଓσʔλΛͲ͏ѻ͏͔͸ݴޠ͕ࢦࣔͯ͘͠Εͳ͍ – )BTLFMM΍ 4DBMBɺ'ͳͲͱಉ༷ͷΞϓϩʔνΛͱΖ͏ʹ΋ɺݴޠͷαϙʔτػߏ͕ෆे෼ – αʔυύʔςΟϥΠϒϥϦͰʮิ͏ʯఔ౓͕ݶ౓͔

Slide 3

Slide 3 text

ͦ΋ͦ΋ʮؔ਺ܕϓϩάϥϛϯάʯͬͯ • ໋ྩܕ ؔ਺ܕ – จ ໭Γ஋Λ൐Θͳ͍ ͰܭࢉΛߏ੒͢Δ uuu ໋ྩܕ – ࣜ ໭Γ஋Λ൐͏ ͰܭࢉΛએݴ͢Δ uuu ؔ਺ܕ • ؔ਺ܕϓϩάϥϛϯάͬΆ͍ΠσΟΦϜ – NBQSFEVDF – ෦෼ద༻ɺΧϦʔԽ • ܕγεςϜ – ୅਺తσʔλܕͱύλʔϯϚον – จ຺෇͖ܭࢉɺϞφυɺܕΫϥεɺߴ֊ଟ૬uuu • Πϛϡʔλϒϧ ϛϡʔλϒϧ – Ӭଓσʔλ

Slide 4

Slide 4 text

໋ྩܕGPSจͰॻ͘ int total = 0; for (int i = 1; i <= n; i++) { total += i; } • GPSจͱ୅ೖจͰɺ܁Γฦ͠ԋࢉ݁ՌΛॻ͖ࠐΉ ୅ೖ͢Δ ໋ྩΛߦ͍ͬͯΔ • ܭࢉػ΁ͷ໋ྩ uuu໋ྩܕ • จͰܭࢉΛߏ੒͢Δͱɺ໋ྩతʹͳΔ

Slide 5

Slide 5 text

ؔ਺ܕ࠶ؼతʹؔ਺Λద༻͢Δ • ࣜʹΑΓܭࢉΛએݴ͢Δ • ࣜ͸ඞͣ஋Λ໭͢ɻͦͷ஋ʹ࠶ͼؔ਺Λద༻͢Δ • ࣜͰܭࢉΛߏ੒͢ΔͱɺએݴతʹͳΔ let s = foldl (+) 0 [1 .. n] )BTLFMM let s = [1, 2, 3, 4, 5].reduce((acc, i) => acc + i, 0)``` let s = [1, 2, 3, 4, 5].reduce((acc, i) => acc + i, 0) 5ZQF4DSJQU

Slide 6

Slide 6 text

ؔ਺ʹΑΔΦϒδΣΫτͷঢ়ଶભҠ ͋Δঢ়ଶ Tʹؔ਺ GΛద༻ͯ͠ɺผͷঢ়ଶ TΛಘΔ // 顧客をアーカイブ状態にする export const archiveCustomer = (customer: Customer): Customer => ({ ...customer, archived: true, })) 5ZQF4DSJQU 𝑠 𝑠′ 𝑓

Slide 7

Slide 7 text

customer.archive() 5ZQF4DSJQU const archived = archiveCustomer(customer) 5ZQF4DSJQU • ໋ྩతʹॻ͘ – ΦϒδΣΫτͷ಺෦ঢ়ଶΛॻ͖׵͑Δ໋ྩΛߦ͏͜ͱͰɺঢ়ଶΛมԽͤ͞Δ – ঢ়ଶͷมԽ͕҉໧త • ؔ਺త એݴత ʹॻ͘ – Ҿ਺ͷΦϒδΣΫτʹؔ਺Λద༻ͯ͠ɺঢ়ଶભҠޙͷΦϒδΣΫτΛಘΔ – ભҠલͷঢ়ଶ͸ඞͣҾ਺ʹݱΕɺભҠޙͷঢ়ଶ͸໭Γ஋ʹݱΕΔ

Slide 8

Slide 8 text

𝑓 ͱ͋Δू߹4 ·ͨଞͷू߹4 ͋Δू߹ʹଐ͢Δ஋Λɺؔ਺ GʹΑΓɺ·ͨଞͷू߹ʹଐ͢Δ஋ʹࣸ͢ ͜Ε͕ͲΜͳू߹͔هड़͢Δͷ͕ʮܕʯ

Slide 9

Slide 9 text

એݴతʹؔ਺Λهड़͢Δͷ͸΍Γ΍͍͢ݴޠ • ୈҰڃؔ਺ɺߴ֊ؔ਺ɺΫϩʔδϟ • ؔ਺Ϧςϥϧ • ෼ׂ୅ೖ • NBQSFEVDF • ੩తܕ෇͚ɺܕਪ࿦ ʮࣜͰܭࢉΛએݴతʹఆٛ͢Δʯͱ͍͏఺ʹ͓͍ͯ͸े෼ͳػೳΛ༗͢Δ ෼ׂ୅ೖͷγϯλοΫεͰΠϛϡʔλϒϧͳؔ਺΋هड़͠΍͍͢

Slide 10

Slide 10 text

ΧϦʔԽ͸ݴޠͷػೳͱͯ͠͸ͳ͍͕ɺࣗ෼Ͱهड़͢Ε͹ྑ͍ • ΫϩʔδϟΛฦؔ͢਺ͱͯ͠ఆٛ͢Ε͹Α͍ • ෦෼ద༻ʹΑΔ %FQFOEFODZ*OKFDUJPO ͳͲʹ΋ॏཁ export type getTagSortOrder = ({ groupId }: { groupId: RestaurantGroupId }) => ResultAsync export const getTagSortOrder = ({ prisma }: applicationContext): getTagSortOrder => ({ groupId }) => ResultAsync.fromPromise( prisma.tag .aggregate({ _max: { sortOrder: true, }, where: { groupId }, }) .then((x) => (x._max.sortOrder ? x._max.sortOrder + 1 : 1)), PrismaClientError )

Slide 11

Slide 11 text

5ZQF4DSJQUͷܕγεςϜ • ߏ଄త෦෼ܕ TUSVDUVSBMTVCZQF ͰߴػೳͳܕγεςϜɾܕਪ࿦ – Ϧςϥϧܕ – δΣωϦΫε – ߹ซܕ 6OJPO ަࠩܕ *OUFSTFDUJPO – ಈతͳܕఆٛ uuu $POEJUJPJOBM5ZQFTɺ6UJMJUZ5ZQFTɺ.BQQFE5ZQFTɺJOGFS • ҎԼ͸ɺΤϛϡϨʔτͰ͖Δ – ୅਺తσʔλܕͱύλʔϯϚον • Ͱ͸͋Δ͕ɺҎԼ͸ͳ͍ – 0QUJPOBM΍ 3FTVMUͳͲΛந৅తʹѻ͏࢓૊Έ uuu Ϟφυ΍ܕΫϥεɺߴ֊ଟ૬ FUD

Slide 12

Slide 12 text

୅਺తσʔλܕ uuu ੩తܕ෇͚ͷؔ਺ܕݴޠͰσʔλߏ଄Λఆٛ͢Δखஈ • )BTLFMMͳͲͷݴޠͰ͸σʔλߏ଄Λఆٛ͢Δͷʹ୅਺తσʔλܕͰදݱ͢Δ • ܕΛ૊Έ߹ΘͤΔͷʹੵ "/% ͚ͩͰͳ͘ ࿨ 03 ͕࢖͑Δ data Bool = True | False data Maybe a = Nothing | Just a )BTLFMM )BTLFMM data UnionFind = UnionFind { parent :: IM.IntMap Int, size :: IM.IntMap Int } )BTLFMM

Slide 13

Slide 13 text

࿨Ͱ૊Έ߹Θͤͯߏஙͨ͠΋ͷ͸ɺύλʔϯϚονͰ෼ղ main = do let someValue :: Maybe String someValue = ... case someValue of Just s -> putStrLn (s ++ ", naoya") Nothing -> putStrLn "Farewell" data Maybe a = Nothing | Just a )BTLFMM )BTLFMM +VTU4USJOH͔ /PUIJOHͷͲͪΒ͔ .BZCFܕΛύλʔϯϚονͰ෼ղ͢Δ

Slide 14

Slide 14 text

5ZQF4DSJQU͸૊ΈࠐΈͰ͸୅਺తσʔλܕΛαϙʔτͯ͠ͳ͍͕ɺΤϛϡϨʔτͰ͖Δ interface Empty { kind: "Empty" } interface Cons { kind: "Cons" head: T tail: List } export type List = Empty | Cons data List a = Empty | Cons a (List a) 5ZQF4DSJQU )BTLFMM ϦςϥϧܕͰλάΛ͚͓ͭͯ͘ ϢχΦϯͰ૊Έ߹Θͤͨܕ

Slide 15

Slide 15 text

// List への map 関数を実装 type map = (f: (a: T) => U, xs: List) => List export const map: map = (f, xs) => { switch (xs.kind) { case "Empty": return Empty() case "Cons": return Cons(f(xs.head), map(f, xs.tail)) default: assertNever(xs) } } export function assertNever(_: never): never { throw new Error() } console.log(map(i => i * 2, myList)) 5ZQF4DSJQU λάʹԠͯ͡෼ղ ϦςϥϧܕͳͷͰͪΌΜͱܕ͕ޮ͘ ͜ΕΛೖΕΔ͜ͱͰ໢ཏੑνΣοΫ͕ޮ͘

Slide 16

Slide 16 text

͜͜·ͰݟΔͱؔ਺ܕελΠϧͰ΍͍ͬͯ͘ͷʹे෼ʹݟ͑Δ • એݴతΠσΟΦϜ͸ॻ͖΍͍͢ • ෼ׂ୅ೖͰΠϛϡʔλϒϧʹσʔλߋ৽͢Δͷ΋΍Γ΍͍͢ • ߴػೳͳܕγεςϜ • ΧϦʔԽ΍୅਺తσʔλܕͬΆ͍͜ͱ΋Ͱ͖Δ

Slide 17

Slide 17 text

଍Γͳ͍ͱࢥ͍ͬͯΔ఺ ओ؍ • 0QUJPOBMɺ3FTVMU ͳͲʮจ຺෇͖ܭࢉʯͷͨΊͷܕ͕ͳ͍ɻ·ͨͦΕΛѻ͏ࢧԉػߏ͕ͳ͍ • Ӭଓσʔλߏ଄͕جຊʹ͸ͳ͍ͬͯͳ͍ ۀ຿ΞϓϦέʔγϣϯࢹ఺Ͱ͸จ຺ ෇͖ܭࢉʹର͢Δػߏ͕ͳ͍ͷ͕ɺ ࠷΋೰·͍͠

Slide 18

Slide 18 text

export function toColor(value: string): Result { return /^#[0-9a-f]{3}([0-9a-f]{3})?$/i.test(value) ? ok(value as Color) : err(new ValidationError('⾊の値が不正です。#FFFFFF形式で指定してください')) } 5ZQF4DSJQU 3FTVMUܕ uuu੒ޭ ࣦഊͷ෼ذΛܕͰදݱͰ͖Δ OFWFSUISPXɺGQUTɺ&GGFDUͳͲ͕ಉ༷ͷܕΛϥΠϒϥϦͰఏڙ͢Δ

Slide 19

Slide 19 text

3FTVMUܕͰɺࣦഊͷՄೳੑͷ͋ΔܭࢉΛҰຊಓʹ߹੒͢Δ͜ͱ͕Ͱ͖Δ import { Result, ok, err } from 'neverthrow' function itsUnder100(n: number): Result { return n <= 100 ? ok(n) : err(new Error('100より大きい数字です')) } function itsEven(n: number): Result { return n % 2 == 0 ? ok(n) : err(new Error('奇数です')) } function itsPositive(n: number): Result { return n > 0 ? ok(n) : err(new Error('負数です')) } const result = ok(96).andThen(itsUnder100).andThen(itsEven).andThen(itsPositive) result.match( (n) => console.log(n), (error) => { throw error } )

Slide 20

Slide 20 text

͔͠͠ɺ3FTVMUܕʹೖͬͨ஋͕ೖΕࢠʹͳΔͱ΍΍͍͜͠ export const Tag = (input: TagInput): Result => { const tagId = TagId(input.id) const groupId = RestaurantGroupId(input.groupId) const label = TagLabel(input.label) const icon = input.icon && input.iconType ? TagIcon({ symbol: input.icon, type: input.iconType, color: input.color, }) : ok(NoIcon()) const sortOrder = FractionalIndex(input.sortOrder) const values = Result.combine(tuple(tagId, groupId, label, icon, sortOrder)) return values.map(([id, groupId, label, icon, sortOrder]) => ({ ...input, id, groupId, label, icon, sortOrder, })) } ஋͕͍͍ͩͨ3FTVMUʹೖ͍ͬͯΔ ͨΊɺෳ਺3FTVMU͕͋Δͱ߹੒͠ ͯϑϥοτʹ͢Δඞཁ͕͋Γ໘౗ ͳ࡞ۀʹͳͬͯ͘Δ

Slide 21

Slide 21 text

ʮίϯςφʹೖͬͨจ຺͖ͭͷ஋ʯΛѻ͏ɺ૊ΈࠐΈͷػೳ͕͋ΔݴޠͳΒuuu ͜ͷखͷػߏ͕͋Ε͹ೝ஌ෛՙ௿࣮͘૷Ͱ͖Δ͕ɺ࢒೦ͳ͕Β 5ZQF4DSJQUʹ͸ͳ͍ GQUT΍ &GGFDU͕ϑϥοτ߹੒ͷؔ਺ QJQF Λఏڙͯ͠͸͍Δ͕ɺॻ͖ຯ͸ྑ͘ͳ͍ makeTagId :: String -> Either ValidationError TagId makeTagId tagId | null tagId = Left (ValidationError "tagId is empty") | otherwise = Right (TagId tagId) makeTag :: String -> String -> Int -> Either ValidationError Tag makeTag id gid order = do tagId <- makeTagId id groupId <- makeGroupId gid sortOrder <- makeSortOder order return (Tag tagId groupId sortOrder) )BTLFMM ྫ͑͹Ϟφυʹ͸ɺೖΕࢠʹ ͳͬͨίʔυΛฏୱԽ͢Δޮ༻ ͕͋Δ

Slide 22

Slide 22 text

ӬଓσʔλϓϩάϥϛϯάɺӬଓσʔλߏ଄ ʦೖ໳ʧؔ਺ϓϩάϥϛϯάʕ࣭ͷߴ͍ίʔυΛ͢͹΍͘௚ײతʹॻ͚Δʂ IUUQTHJIZPKQEFWGFBUVSFGVODUJPOBMQSPH

Slide 23

Slide 23 text

Ӭଓσʔλߏ଄ • มߋ͞ΕΔࡍʹมߋલͷόʔδϣϯΛৗʹอ࣋͢Δσʔλߏ଄ • 4USVDUVSBM4IBSJOHʹΑΓɺޮ཰తʹͦΕΒͷσʔλΛอ࣋͢Δ • Πϛϡʔλϒϧʹσʔλߏ଄Λมߋ͢Δͱ͖ɺશମΛίϐʔ͠ͳͯ͘ࡁΉ https://vimeo.com/166790294

Slide 24

Slide 24 text

)BTLFMMͷجຊతͳσʔλߏ଄͸Ӭଓσʔλߏ଄ main :: IO () main = do let xs = scanl' (flip Set.insert) Set.empty [1 .. 10 ^ 5] print $ Set.size (last xs) )BTLFMM Ӭଓσʔλߏ଄ͳΒΠϛϡʔλϒϧʹσʔλΛѻ͍ͭͭύϑΥʔϚϯεͱཱ྆Ͱ͖Δ ݸͷ 4FU͕࡞ΒΕΔ͕ͦͷ౎ ౓શମ͕ຖճίϐʔ͞ΕΔΘ͚Ͱ ͸ͳ͍

Slide 25

Slide 25 text

5ZQF4DSJQUͱӬଓσʔλߏ଄ • ૊ΈࠐΈͷσʔλߏ଄͸Ӭଓσʔλߏ଄Ͱ͸ͳ͘ɺجຊ͸ϛϡʔλϒϧ • *NNVUBCMFKTͳͲӬଓσʔλߏ଄Λఏڙ͢ΔϥΠϒϥϦ͕͋Δ͕ɺ͍·͍ͪྲྀߦͬͯͳ͍ – ۀ຿ΞϓϦέʔγϣͰ͸Ӭଓσʔλߏ଄Λ࢖͏ඞཁͷ͋Δ΄ͲɺύϑΥʔϚϯεཁ͕݅ݫ͍͠৔໘͕গͳ͍

Slide 26

Slide 26 text

࠶ܝ ૯࿦ • ؔ਺ܕϓϩάϥϛϯάͷΤοηϯεΛऔΓೖΕΔ͜ͱͰΑΓྑ͍ϓϩάϥϛϯά͕Ͱ͖Δݴޠ – 3FBDUͳͲ͕ྑ͍ྫ – ߴػೳͳܕγεςϜɺؔ਺Ϧςϥϧɺߴ֊ؔ਺ɺΫϩʔδϟɺNBQSFEVDFɺ෼ׂ୅ೖͳͲͷγϯλοΫεαϙʔτ – ୅਺తσʔλܕ΋ΤϛϡϨʔτ͸Ͱ͖Δ • )BTLFMM΍ 4DBMBͷΑ͏ͳؔ਺ܕϓϩάϥϛϯάݴޠʹൺֱ͢Δͱػೳ͸ෆ଍͍ͯ͠Δ – ͦΕ͕ࠓޙɺվྑ͞Ε͍ͯ͘ϩʔυϚοϓ͸ߟ͑ʹ͍͘ • ྫ֎΍ΤϥʔΛؚΉ෭࡞༻ΛͲ͏ѻ͏͔ɺӬଓσʔλΛͲ͏ѻ͏͔͸ݴޠ͕ࢦࣔͯ͘͠Εͳ͍ – )BTLFMM΍ 4DBMBɺ'ͳͲͱಉ༷ͷΞϓϩʔνΛͱΖ͏ʹ΋ɺݴޠͷαϙʔτػߏ͕ෆे෼ – αʔυύʔςΟϥΠϒϥϦͰʮิ͏ʯఔ౓͕ݶ౓͔

Slide 27

Slide 27 text

ࢲݟ • 5ZQF4DSJQU͸ؔ਺ܕϓϩάϥϛϯάʹಛԽͨ͠ݴޠͰ͸ͳ͍ͨΊɺؔ਺ܕʹدͤ͗͢Δͷ΋ߟ͑΋ͷ – खଓ͖తʹॻ͚͹Α͍ͱ͜Ζ͸ɺखଓ͖Λ࢖͏ – ಛʹ *0΍ඇಉظॲཧपΓ͸ແཧʹؔ਺ܕʹ͢Δඞཁ͸ͳ͍ • )BTLFMMͳͲଞͷؔ਺ܕݴޠͰ΋ɺ࡞༻Λ൐͏ͱ͜Ζ͸खଓ͖తʹ࣮૷͢Δ͜ͱ΋ଟ͍ – ࢀߟʰ5ZQF4DSJQUͰͲ͜·Ͱʮؔ਺ܕϓϩάϥϛϯάʯ͢Δ͔ ᴷʮखଓ͖ )BTLFMMʯ͔Βߟ࡯͢Δʱ • IUUQTVTFSGJSTUJLZVDPKQFOUSZ • *0෼཭Λੵۃతʹߦͬͯۀ຿ϩδοΫΛ७ਮʹ͠ɺ७ਮؔ਺Ͱߏ੒͢Δͷ͸ྑ͍ϓϥΫςΟεͩͱࢥ͏