We Are PureScripters! #1 ハンズオン / We Are PureScripters #1 Handson

5f533aeab28ed4f70c26e336e71296f7?s=47 tipo159
July 17, 2017

We Are PureScripters! #1 ハンズオン / We Are PureScripters #1 Handson

5f533aeab28ed4f70c26e336e71296f7?s=128

tipo159

July 17, 2017
Tweet

Transcript

  1. 5.

    1ষ ং࿦ ؔ਺ܕJavaScript (4/4) +BWB4DSJQU 1VSF4DSJQU ߏจ ৑௕ ͱͯ΋දݱྗ๛͔Ͱ͋Γ ͳ͕ΒΘ͔Γ΍͘͢ಡΈ

    ΍͍͢ίʔυΛॻ͚ΔΑ ͏ʹ͢Δɺܰྔͳߏจ ܕ ܕ෇͚͞Εͳ͍ ڧྗͳந৅ԽΛఏڙ͢Δ ๛͔ͳܕγεςϜ ཧղ͠΍͢͞ ຉ์ʹॻ͔Εͨ JavaScriptίʔυͷཧղ ͸೉͍͠ ߴ଎Ͱཧղ͠΍͍͢ίʔ υΛੜ੒ 5
  2. 6.

    1ষ ং࿦ ܕͱܕਪ࿦ (1/5) • PureScript͸੩తܕ෇͚ͷݴޠ • ਖ਼͍͠ϓϩάϥϜ͸ίϯύΠϥʹΑͬͯͦͷಈ࡞Λࣔ͢Α͏ͳܕ Λ༩͑ΒΕΔݴޠ •

    ܕΛ༩͑Δ͜ͱ͕Ͱ͖ͳ͍ϓϩάϥϜ͸ޡͬͨϓϩάϥϜͰ͋ ΓɺίϯύΠϥʹΑͬͯڋ൱͞ΕΔ • ಈతܕ෇͚ͷݴޠͱ͸ҟͳΓɺPureScriptͰ͸ܕ͸ίϯύΠϧ࣌ ͷΈʹଘࡏ͠ɺ࣮ߦ࣌ʹ͸ܕͷදݱ͸ͳ͍ 6
  3. 8.

    1ষ ং࿦ ܕͱܕਪ࿦ (3/5) • PureScriptͷܕγεςϜ͸ɺܕਪ࿦(type inference)Λαϙʔτ • ܕਪ࿦ʹ͸ɺ࠷௿ݶͷ໌ࣔతͳܕ஫ऍ͚͕ͩඞཁ •

    ܕγεςϜ͸ɺ໽հऀͰ͸ͳ͘ಓ۩ • ࣍ͷίʔυ͸਺Λఆ͍ٛͯ͠Δ͕ɺ Numberܕͩͱ͍͏஫ऍ͸ͳ͍ iAmANumber = let square x = x * x in square 42.0 8
  4. 9.

    1ষ ং࿦ ܕͱܕਪ࿦ (4/5) • ࣍ͷྫͰ͸ɺίϯύΠϥʹͱͬͯະ஌ͷܕ͕ଘࡏ͠΋ɺܕ஫ऍͳ͠ Ͱܕͷਖ਼͠͞Λ͔֬ΊΔ͜ͱ͕Ͱ͖Δ iterate f 0

    x = x iterate f n x = iterate f (n - 1) (f x) • ͜͜Ͱxͷܕ͸ෆ໌͕ͩɺx͕ͲΜͳܕΛ͍࣋ͬͯΔ͔ʹ͔͔ΘΒ ͣɺiterate͕ܕγεςϜͷنଇʹै͍ͬͯΔ͜ͱΛίϯύΠϥ͸ ݕূ͢Δ 9
  5. 10.

    1ষ ং࿦ ܕͱܕਪ࿦ (5/5) • ੩తܕ͸ɺϓϩάϥϜͷਖ਼͠͞ʹ͍ͭͯͷ֬৴ΛಘΔͨΊ͚ͩͰ͸ ͳ͘ɺͦͷਖ਼͠͞ʹΑͬͯ։ൃΛॿ͚Δ • JavaScriptͰίʔυͷେن໛ͳϦϑΝΫλϦϯάΛ͢Δ͜ͱ͸೉͠ ͍Ͱ͕͢ɺܕݕূثͷ͋Δදݱྗ๛͔ͳܕγεςϜΛ࣋ͭ

    PureScriptͰ͸ɺର࿩తʹϦϑΝΫλϦϯάͰ͖Δ • ܕγεςϜʹΑͬͯఏڙ͞ΕͨηʔϑςΟωοτ͸ɺΑΓߴ౓ͳந ৅ԽΛՄೳʹ͢Δ • ؔ਺ܕϓϩάϥϛϯάݴޠHaskellʹΑͬͯ஌ΒΕΔΑ͏ʹͳͬ ͨɺܕओಋͷڧྗͳந৅ԽͰ͋ΔܕΫϥεΛPureScript͸උ͍͑ͯ Δ 10
  6. 11.

    1ষ ং࿦ ଟݴޠWebϓϩάϥϛϯά (1/2) • ؔ਺ܕϓϩάϥϛϯά͸͢Ͱʹଟ͘ͷ੒ޭΛऩΊͯΔ • ಛʹ੒ޭ͍ͯ͠ΔԠ༻ྫ͸ɺσʔλղੳɺߏจղੳɺίϯύΠϥ ͷ࣮૷ɺδΣωϦοΫϓϩάϥϛϯάɺฒྻॲཧͳͲ •

    PureScriptͷΑ͏ͳؔ਺ܕݴޠͰ΋ɺΞϓϦέʔγϣϯ։ൃͷ࠷ॳ ͔Β࠷ޙ·ͰΛ࣮ࢪ͢Δ͜ͱ͕Մೳ • ஋΍ؔ਺ͷܕΛఏڙ͢Δ͜ͱͰطଘͷJavaScriptίʔυΛΠϯϙʔ τ͠ɺ௨ৗͷPureScriptίʔυ͔Β͜ΕΒͷؔ਺Λ࢖༻͢ΔػೳΛ PureScript͸ఏڙ 11
  7. 12.

    1ষ ং࿦ ଟݴޠWebϓϩάϥϛϯά (2/2) • PureScriptͷڧΈͷͻͱͭ͸ɺJavaScriptΛର৅ͱ͢Δଞͷݴޠͱͷ ૬ޓӡ༻ੑʹ͋Δ • ΞϓϦέʔγϣϯͷ։ൃͷҰ෦ʹ͚ͩPureScriptΛ࢖༻͠ɺ JavaScriptͷ࢒Γͷ෦෼ΛଞͷݴޠͰهड़͢Δ͜ͱ΋Մೳ

    • த֩ͱͳΔॲཧ͸PureScriptͰهड़͠ɺϢʔβʔΠϯλʔϑΣʔ ε͸JavaScriptͰهड़͢Δ • JavaScript΍ɺଞͷJavaScriptʹίϯύΠϧ͞ΕΔݴޠͰΞϓϦ έʔγϣϯΛॻ͖ɺPureScriptͰͦͷςετΛॻ͘ • طଘͷΞϓϦέʔγϣϯͷϢʔβΠϯλϑΣʔεͷςετΛࣗಈ Խ͢ΔͨΊʹɺPureScriptΛ࢖༻͢Δ 12
  8. 14.

    2ষ ͸͡Ίʹ Hello, PureScript! (1/3) • ۭσΟϨΫτϦʹ pulp initίϚϯυͰϓϩδΣΫτΛ࡞Δ $

    mkdir my-project $ cd my-project $ pulp init * Generating project skeleton in ~/my-project $ ls bower.json bower_components src test • pulp͸bower_componentsɺ srcͱtestͷࡾͭͷσΟϨΫτϦͱ bower.jsonίϯϑΟάϨʔγϣϯϑΝΠϧΛ࡞੒ • src͸ιʔεϑΝΠϧΛ֨ೲ͢ΔσΟϨΫτϦͰɺ test͸ςετΛ ֨ೲ͢ΔσΟϨΫτϦ 14
  9. 15.

    2ষ ͸͡Ίʹ Hello, PureScript! (2/3) • src/Main.pursΛԼهͷΑ͏ʹमਖ਼ module Main where

    import Control.Monad.Eff.Console main = log "Hello, World!" • ͢΂ͯͷιʔεϑΝΠϧ͸Ϟδϡʔϧϔομ͔Β࢝·Δ • Ϟδϡʔϧ໊͸ɺυοτͰ۠੾ΒΕͨେจࣈͰ࢝·Δ1ͭҎ্ͷ୯ޠͰߏ੒ • ͜ͷྫ͸Ϟδϡʔϧ໊ͱͯ͠ͻͱͭͷ୯ޠ͚͕ͩ࢖༻͞Ε͍ͯΔ͕ɺ My.First.Moduleͱ͍͏Α͏ͳϞδϡʔϧ໊΋༗ޮ • Ϟδϡʔϧ͸ɺϞδϡʔϧ໊ͷ֤෦෼Λ۠੾ΔͨΊͷυοτΛؚΊͨɺ׬શͳ໊લΛ࢖ ༻ͯ͠Πϯϙʔτ • ͜ͷྫ͸logؔ਺Λఏڙ͢ΔControl.Monad.Eff.ConsoleϞδϡʔϧΛΠϯϙʔτ • ͜ͷmainϓϩάϥϜͷఆٛຊମ͸ɺؔ਺ద༻ͷࣜ • PureScriptͰ͸ɺؔ਺ద༻͸ؔ਺໊ͷޙʹҾ਺ΛۭനͰ۠੾ͬͯॻ͘ 15
  10. 16.

    2ষ ͸͡Ίʹ Hello, PureScript! (3/3) • ͜ͷίʔυΛϏϧυ࣮ͯ͠ߦ $ pulp run

    * Building project in ~/my-project * Build successful. Hello, World! 16
  11. 17.

    2ষ ͸͡Ίʹ ϒϥ΢βͷͨΊͷίϯύΠϧ • Pulp͸ɺpulp browserifyίϚϯυͰPureScriptίʔυΛWebϒϥ΢βʹ దͨ͠JavaScriptʹม׵ $ pulp browserify

    * Browserifying project in ~/my-project * Building project in ~/my-project * Build successful. * Browserifying... • େྔͷJavaScript͕ίϯιʔϧʹग़ྗ͞ΕΔ • ͜Ε͸ɺPreludeͱ͍͏໊લͷඪ४PureScriptϥΠϒϥϦͱsrcσΟϨΫτϦ ಺ͷίʔυʹɺBrowserifyπʔϧΛద༻ͨ͠Ξ΢τϓοτ • Javascriptίʔυ͸ϑΝΠϧʹηʔϒͰ͖ɺHTMLॻྨʹؚΊΔ͜ͱ΋Ͱ͖Δ • ͜ΕΛࢼ͢ͱɺϒϥ΢βͷίϯιʔϧʹ"ɺHello, World!"͕ग़ྗ͞ΕΔ 17
  12. 18.

    2ষ ͸͡Ίʹ ࢖༻͞Ε͍ͯͳ͍ίʔυΛऔΓআ͘ (1/3) • Pulp͸pulp buildͱ͍͏ผͷίϚϯυΛఏڙ • ࢖༻͞Εͳ͍ίʔυΛ࡟আ͢Δ-OΦϓγϣϯΛ෇͚ͯɺΞ΢τϓο τ͔ΒෆཁͳJavascriptίʔυΛऔΓআ͘

    • ݁Ռ͸ͣͬͱখ͘͞ͳΔ $ pulp build -O --to output.js * Building project in ~/my-project * Build successful. * Bundling Javascript... * Bundled. 18
  13. 19.

    2ষ ͸͡Ίʹ ࢖༻͞Ε͍ͯͳ͍ίʔυΛऔΓআ͘ (2/3) • ੜ੒͞Εͨίʔυ͸HTMLυΩϡϝϯτͰ࢖༻Ͱ͖Δ • output.jsΛΦʔϓϯ͢ΔͱɺԼهͷΑ͏ͳίϯύΠϧ͞ΕͨϞ δϡʔϧ͕ݟ͔ͭΔ (function(exports)

    { "use strict"; var Control_Monad_Eff_Console = PS["Control.Monad.Eff.Console"]; var main = Control_Monad_Eff_Console.log("Hello, World!"); exports["main"] = main; })(PS["Main"] = PS["Main"] || {}); 19
  14. 20.

    2ষ ͸͡Ίʹ ࢖༻͞Ε͍ͯͳ͍ίʔυΛऔΓআ͘ (3/3) • PureScriptίϯύΠϥ͕JavascriptίʔυΛੜ੒͢Δํ๏ͷཁ఺ • ͢΂ͯͷϞδϡʔϧ͸ΦϒδΣΫτʹม׵͞ΕɺͦͷΦϒδΣΫτʹ ͸ͦͷϞδϡʔϧͷΤΫεϙʔτ͞Εͨϝϯόؚ͕·Ε͍ͯΔ •

    PureScript͸ՄೳͳݶΓม਺ͷ໊લΛͦͷ··࢖͏ • PureScriptʹ͓͚Δؔ਺ద༻͸ɺͦͷ··JavaScriptͷؔ਺ద༻ʹม׵ • Ҿ਺ͷͳ͍୯७ͳݺͼग़͠ͱͯ͠ϝΠϯϝιουݺͼग़͕͠ੜ੒͞Εɺ ͢΂ͯͷϞδϡʔϧ͕ఆٛ͞Εͨޙʹ࣮ߦ͞ΕΔ • PureScriptίʔυ͸ͲΜͳ࣮ߦ࣌ϥΠϒϥϦʹ΋ґଘ͠ͳ͍ • ίϯύΠϥʹΑͬͯੜ੒͞ΕΔ͢΂ͯͷίʔυ͸ɺ͋ͳͨͷίʔυ͕ ґଘ͢Δ͍ͣΕ͔ͷPureScriptϞδϡʔϧΛ΋ͱʹग़ྗ͞Ε͍ͯΔ • PureScript͸γϯϓϧͰཧղ͠΍͍͢ίʔυΛੜ੒͢Δ͜ͱॏࢹ͍ͯ͠Δ 20
  15. 21.

    2ষ ͸͡Ίʹ CommonJSϞδϡʔϧͷίϯύΠϧ • Pulp͸PureScriptͷίʔυ͔ΒCommonJSϞδϡʔϧΛੜ੒Ͱ͖Δ • ͜Ε͸NodeJSͰ࢖͏ͱ͖΍CommonJSΛ࢖ͬͨେن໛ϓϩδΣΫτ ͰίʔυΛখ͞ͳίϯϙʔωϯτʹ෼ׂ͢Δͱ͖ʹ໾ʹཱͭ • CommonJSϞδϡʔϧΛ࡞੒͢ΔͨΊʹ͸ɺpulp

    buildίϚϯυΛ -OΦϓγϣϯͳ͠Ͱ࢖͏ $ pulp build * Building project in ~/my-project * Build successful. • ੜ੒͞ΕͨϞδϡʔϧ͸σϑΥϧτͰoutputσΟϨΫτϦʹஔ͔ΕΔ • ֤PureScriptϞδϡʔϧ͸ɺͦΕͧΕͷαϒσΟϨΫτϦʹݸผͷ CommonJSϞδϡʔϧͱͯ͠ίϯύΠϧ͞ΕΔ 21
  16. 22.

    2ষ ͸͡Ίʹ BowerʹΑΔґଘؔ܎ͷ௥੻ • diagonalؔ਺Λॻͨ͘Ίʹ͸ɺฏํࠜΛܭࢉͰ͖ΔΑ͏ʹ͢Δඞ ཁ͕͋Δ • JavaScriptͷMathΦϒδΣΫτͷϓϩύςΟͱͯ͠ఆٛ͞Ε͍ͯΔ ؔ਺ͷܕఆؚ͕ٛ·ΕͯΔpurescript-mathύοέʔδΛΠϯε τʔϧ

    $ bower install purescript-math —save • --saveΦϓγϣϯ͸ɺґଘؔ܎Λbower.jsonίϯϑΟΪϡϨʔ γϣϯϑΝΠϧʹ௥Ճ • purescript-mathϥΠϒϥϦͷιʔε͸ɺbower_components αϒσΟϨΫτϦʹΠϯετʔϧ͞ΕɺϓϩδΣΫτΛίϯύΠϧ ͢Δͱ͖ʹҰॹʹίϯύΠϧ͞ΕΔ 22
  17. 23.

    2ষ ͸͡Ίʹ ର֯ઢͷ௕͞ͷܭࢉ (1/2) • ֎෦ϥΠϒϥϦͷؔ਺Λ࢖༻͢Δྫͱͯ͠diagonalؔ਺Λॻ͘ • src/Main.pursϑΝΠϧͷઌ಄ʹ࣍ͷߦΛ௥Ճ͠ɺMathϞδϡʔ ϧΛΠϯϙʔτ import

    Math (sqrt) • ਺஋ͷ଍͠ࢉ΍ֻ͚ࢉͳͲͷجຊతͳૢ࡞Λఆٛͨ͠PreludeϞ δϡʔϧ΋Πϯϙʔτ import Prelude • ࣍ͷΑ͏ʹdiagonalؔ਺Λఆٛ diagonal w h = sqrt (w * w + h * h) 23
  18. 24.

    2ষ ͸͡Ίʹ ର֯ઢͷ௕͞ͷܭࢉ (2/2) • ͜ͷؔ਺ͷܕΛఆٛ͢Δඞཁ͸ͳ͍͜ͱʹ஫ҙ • diagonal͸2ͭͷ਺஋ΛऔΓ਺஋Λฦؔ͢਺Ͱ͋Δ ͱίϯύΠϥ͸ਪ࿦ Ͱ͖Δ

    • ͔͠͠ɺυΩϡϝϯτͱͯ͠΋໾ཱͭͷͰɺ௨ৗ͸ܕ஫ऍΛఏڙ • ৽͍͠diagonalؔ਺Λ࢖͏Α͏ʹ mainؔ਺΋มߋ main = logShow (diagonal 3.0 4.0) • pulp runΛ࢖༻ͯ͠ɺϞδϡʔϧΛ࠶ίϯύΠϧ࣮ͯ͠ߦ $ pulp run * Building project in ~/my-project * Build successful. 5.0 24
  19. 26.

    2ষ ͸͡Ίʹ ର࿩ࣜॲཧܥΛ࢖༻ͨ͠ίʔυͷςετ (2/4) • ίϚϯυͷҰཡΛݟΔʹ͸ɺ :?Λೖྗ > :? The

    following commands are available: :? Show this help menu :quit Quit PSCi :reset Reset :browse <module> Browse <module> :type <expr> Show the type of <expr> :kind <type> Show the kind of <type> :show import Show imported modules :show loaded Show loaded modules :paste paste Enter multiple lines, terminated by ^D • TabΩʔΛԡ͢ͱɺࣗ෼ͷίʔυͰར༻Մೳͳ͢΂ͯͷؔ਺ٴͼBower ͷґଘؔ܎ͱPreludeϞδϡʔϧͷϦετΛݟΔ͜ͱ͕Ͱ͖Δ 26
  20. 27.

    2ষ ͸͡Ίʹ ର࿩ࣜॲཧܥΛ࢖༻ͨ͠ίʔυͷςετ (3/4) • PreludeϞδϡʔϧΛΠϯϙʔτ > import Prelude •

    ز͔ͭ਺ࣜΛධՁ > 1 + 2 3 > "Hello, " <> "World!" "Hello, World!” • psciͰ diagonalؔ਺Λࢼ͢ > import Main > diagonal 5.0 12.0 13.0 27
  21. 28.

    2ষ ͸͡Ίʹ ର࿩ࣜॲཧܥΛ࢖༻ͨ͠ίʔυͷςετ (4/4) • psciͰ΋ؔ਺ΛఆٛͰ͖Δ > let double x

    = x * 2 > double 10 20 • :typeίϚϯυͰࣜͷܕΛ֬ೝ > :type true Boolean > :type [1, 2, 3] Array Int • :resetίϚϯυͰɺϝϞϦ಺ʹ͋ΔίϯύΠϧࡁΈͷ͢΂ͯͷϞ δϡʔϧΛΞϯϩʔυ 28
  22. 29.

    2ষ ͸͡Ίʹ ԋश 1. (؆୯) Math.piఆ਺Λ࢖ͬͯɺ༩͑ΒΕͨ൒ܘͷԁͷ໘ੵΛٻΊ ΔcircleAreaؔ਺Λॻ͍͍ͯͩ͘͞ɻॻ͍ͨؔ਺ΛPSCiΛ࢖ͬ ͯςετ͍ͯͩ͘͠͞ɻ(ώϯτ: import MathจΛpiΛΠϯϙʔ

    τ͢ΔΑ͏ʹมߋ͢Δ͜ͱΛ๨Εͳ͍Ͱ͍ͩ͘͞ɻ) 2. (΍΍೉͍͠) bower installΛ࢖ͬͯɺґଘ͢Δύοέʔδͱ͠ ͯpurescript-globalsΛΠϯετʔϧ͍ͯͩ͘͠͞ɻͦͷؔ਺Λ PSCiͰςετ͍ͯͩ͘͠͞ɻ(ώϯτ: PSCiͷ:browseίϚϯυͰ Ϟδϡʔϧͷ಺༰Λϒϥ΢ζͰ͖·͢ɻ) 29
  23. 30.

    3ষ ؔ਺ͱϨίʔυ ͜ͷষͷ໨ඪ • ͜ͷষͰ͸ɺؔ਺͓ΑͼϨίʔυΛֶͿ • ͲͷΑ͏ʹPureScriptϓϩάϥϜΛߏ଄Խ͢Δͷ͔ɺͲͷΑ͏ʹܕΛ ϓϩάϥϜ։ൃʹ໾ཱͯΔ͔ • ి࿩൪߸ͷҰཡΛ؅ཧ͢Δ؆୯ͳॅॴ࿥ΞϓϦέʔγϣϯΛ࡞੒

    • PureScriptͷߏจ͔Β͍͔ͭ͘ͷ৽͍֓͠೦Λ঺հ • ͜ͷΞϓϦέʔγϣϯͷϑϩϯτΤϯυʹ͸PSCiΛ࢖͏͕ɺ JavaScriptͰϑϩϯτΤϯυΛॻ͘͜ͱ΋Ͱ͖Δ • ޙͷষͰɺϑΥʔϜͷݕࠪ΍ηʔϒ/ϦετΞػೳΛ௥Ճ 30
  24. 31.

    3ষ ؔ਺ͱϨίʔυ ϓϩδΣΫτͷ४උ (1/3) • ͜ͷষͷιʔείʔυ͸src/Data/AddressBook.purs • ͜ͷϑΝΠϧ͸࣍ͷΑ͏ͳϞδϡʔϧએݴͱΠϯϙʔτҰཡ͔Β࢝ ·Δ module

    Data.AddressBook where import Prelude import Control.Plus (empty) import Data.List (List(..), filter, head) import Data.Maybe (Maybe) 31
  25. 32.

    3ষ ؔ਺ͱϨίʔυ ϓϩδΣΫτͷ४උ (2/3) • ͍͔ͭ͘ͷϞδϡʔϧΛΠϯϙʔτ •Control.PlusϞδϡʔϧ͸ɺempty஋Λఆٛ • Data.ListϞδϡʔϧ͸ɺbowerΛ࢖༻ͯ͠ΠϯετʔϧͰ͖Δ purescript-listsύοέʔδ͕ఏڙ

    • ͜ͷϞδϡʔϧ͸ɺ࿈݁ϦετΛ࢖͏ͨΊʹඞཁͳؔ਺Λఆٛ • Data.MaybeϞδϡʔϧ͸ɺ஋͕ଘࡏͨ͠Γ͠ͳ͔ͬͨΓ͢ΔΑ ͏ͳɺΦϓγϣφϧͳ஋Λѻ͏ͨΊͷσʔλܕͱؔ਺Λఆٛ • ͜ͷϞδϡʔϧͷΠϯϙʔτ಺༰͸ׅހ಺Ͱ໌ࣔతʹྻڍ • ໌ࣔతͳྻڍ͸Πϯϙʔτ಺༰ͷিಥΛආ͚Δͷʹ໾ʹཱͭ 32
  26. 34.

    3ষ ؔ਺ͱϨίʔυ ୯७ͳܕ (1/7) • JavaScriptͷϓϦϛςΟϒܕʹରԠ͢Δ૊ΈࠐΈσʔλܕͱͯ͠ɺPureScript͸ ਺஋ܕͱจࣈྻܕɺਅِܕͷ̏ͭΛఆٛ • ͢΂ͯͷϞδϡʔϧʹ҉໧ʹΠϯϙʔτ͞ΕΔPrimϞδϡʔϧͰ͜ΕΒͷܕ͸ ఆٛ

    • ͜ΕΒͷܕ͸ͦΕͧΕNumberɺStringͱBooleanͱݺ͹ΕɺPSCiͷ:type ίϚϯυΛ࢖༻͢Δͱ؆୯ͳ஋ͷܕΛ֬ೝͰ͖Δ $ pulp psci > :type 1.0 Number > :type "test" String > :type true Boolean 34
  27. 36.

    3ষ ؔ਺ͱϨίʔυ ୯७ͳܕ (3/7) • JavaScriptͷ഑ྻͱ͸ҟͳΓɺPureScriptͷ഑ྻͷཁૉ͸ಉ͡ܕΛ ࣋ͭ > :type [1,

    2, 3] Array Int > :type [true, false] Array Boolean > :type [1, false] Could not match type Int with Boolean. • ࠷ޙͷྫͰى͖͍ͯΔΤϥʔ͸ܕݕূثʹΑͬͯใࠂ͞Εͨ΋ͷͰɺ ഑ྻͷ2ͭͷཁૉͷܕΛ୯ҰԽ(Unification)͠Α͏ͱࣦͯ͠ഊͨ͜͠ ͱࣔ͢ 36
  28. 37.

    3ষ ؔ਺ͱϨίʔυ ୯७ͳܕ (4/7) • Ϩίʔυ͸JavaScriptͷΦϒδΣΫτʹରԠ • ϨίʔυϦςϥϧ͸JavaScriptͷΦϒδΣΫτϦςϥϧͱಉ͡ߏจ > let

    author = { name: "Phil", interests: ["Functional Programming", "JavaScript"] } > :type author { name :: String , interests :: Array String } • ΦϒδΣΫτauthor͸ɺStringܕͷϑΟʔϧυnameͱStringͷ ഑ྻͷܕͷϑΟʔϧυinterestsͱ͍͏;ͨͭͷϑΟʔϧυ(field) Λ࣋ͭ 37
  29. 39.

    3ষ ؔ਺ͱϨίʔυ ୯७ͳܕ (6/7) • ϑΝΠϧͷτοϓϨϕϧͰ͸ɺ౳߸ͷ௚લʹҾ਺Λࢦఆ͢Δ͜ͱͰ ؔ਺Λఆٛ add :: Int

    -> Int -> Int add x y = x + y • όοΫεϥογϡʹʹଓ͚ۭͯനจࣈͰ۠੾ΒΕͨҾ਺໊ͷϦετ Λॻ͘ͱɺؔ਺ΛΠϯϥΠϯͰఆٛ͢ΔͰ͖Δ • ෳ਺ߦͷఆٛΛPSCiʹೖྗ͢Δͱ͖ʹ͸ɺpasteίϚϯυͰ”ϖʔε τϞʔυ"ʹೖΔ͜ͱ͕Ͱ͖Δ • ͜ͷϞʔυͰ͸ɺఆٛ͸Control-DͰऴྃ > :paste … let … add :: Int -> Int -> Int … add = \x y -> x + y … ^D 39
  30. 41.

    3ষ ؔ਺ͱϨίʔυ ྔԽ͞Εͨܕ (1/3) • flipؔ਺͸࣍ͷΑ͏ͳܕΛ͍࣋ͬͯΔ > :type flip forall

    a b c. (a -> b -> c) -> b -> a -> c • ͜ͷforallΩʔϫʔυ͸flip͕શশྔԽ͞Εͨܕ(universally quantified type)Λ͍࣋ͬͯΔ͜ͱΛࣔ͢ • ͜Ε͸ɺa΍bɺcΛͲͷܕʹஔ͖׵͑ͯ΋ɺflip͸ͦͷܕͰ͏·͘ ಈ࡞͢Δͱ͍͏ҙຯ • ྫ͑͹ɺaΛIntɺbΛStringɺcΛStringʹ͢Δ৔߹ɺflipͷ ܕΛ࣍ͷΑ͏ʹಛघԽ(specialize)Ͱ͖Δ (Int -> String -> String) -> String -> Int -> String 41
  31. 42.

    3ষ ؔ਺ͱϨίʔυ ྔԽ͞Εͨܕ (2/3) • ྔԽ͞ΕͨܕͷಛघԽ͸ࣗಈతʹߦΘΕΔ • ͢ͰʹͦͷܕͷflipΛ͍͔࣋ͬͯͨͷΑ͏ʹɺ࣍ͷΑ͏ʹflipΛ ࢖͑Δ >

    flip (\n s -> show n <> s) "Ten" 10 “10Ten” • flip͸ɺೋҾ਺ؔ਺Λड͚औͬͯୈҰҾ਺ͱୈೋҾ਺ΛೖΕସ͑ͨ ؔ਺ʹ͢Δؔ਺ 42
  32. 43.

    3ষ ؔ਺ͱϨίʔυ ྔԽ͞Εͨܕ (3/3) • aɺbɺcͷܕ͸ͲΜͳܕͰ΋બͿ͜ͱ͕Ͱ͖Δͱ͍ͬͯ΋ɺܕͷෆ ੔߹͸ੜ͡ͳ͍Α͏ʹ͠ͳ͚Ε͹ͳΒͳ͍ • flipʹ౉ؔ͢਺ͷܕ͸ɺଞͷҾ਺ͷܕͱ੔߹͠ͳ͚Ε͹ͳΒͳ͍ •

    ୈ̎Ҿ਺ͱͯ͠਺10ɺୈ̏Ҿ਺ͱͯ͠จࣈྻ”Ten”Λ౉͢ͱ͏·͘ ͍͔ͳ͍ > flip (\n s -> show n <> s) 10 "Ten" Could not match type Int with type String 43
  33. 44.

    3ষ ؔ਺ͱϨίʔυ ࣈԼ͛ʹ͍ͭͯͷ஫ҙ (1/3) • JavaScriptͱ͸ҟͳΓɺPureScriptͷίʔυ͸ࣈԼ͛ͷେ͖͞ʹӨڹ͞ΕΔ (indentation-sensitive) • PureScriptͰ͸ۭന͕ίʔυͷ·ͱ·ΓΛࣔ͢ͷʹ࢖ΘΕΔ •

    એݴ͕ෳ਺ߦʹΘͨΔ৔߹͸ɺ̎ͭΊͷߦ͸࠷ॳͷߦͷࣈԼ͛ΑΓਂ͘ࣈԼ͛ ͠ͳ͚Ε͹ͳ͍ • ࣍͸ਖ਼͍͠PureScriptίʔυ add x y z = x + y + z • ࣍͸ਖ਼͍͠ίʔυͰ͸ͳ͍ add x y z = x + y + z • ͦΕͧΕͷߦ͝ͱʹͻͱͭɺͭ·Γ2ͭͷએݴͰ͋Δͱߏจղੳ͢Δ 44
  34. 46.

    3ষ ؔ਺ͱϨίʔυ ࣈԼ͛ʹ͍ͭͯͷ஫ҙ (3/3) • PureScriptͷ͍͔ͭ͘ͷ༧໿ޠʢྫ͑͹ where΍ofɺletʣ͸৽ͨ ͳίʔυͷ·ͱ·ΓΛಋೖ͢Δ • ͦͷίʔυͷ·ͱ·Γ಺ͷએݴ͸ͦΕΑΓਂ͘ࣈԼ͛͞ΕΔ

    example x y z = foo + bar where foo = x * y bar = y * z • ͨͩ͠ɺιʔεϑΝΠϧͷઌ಄ɺ࠷ॳͷ moduleએݴʹ͓͚Δ༧໿ ޠwhere͚ͩ͸ɺ͜ͷنଇͷ།Ұͷྫ֎ 46
  35. 47.

    3ষ ؔ਺ͱϨίʔυ ಠࣗͷܕͷఆٛ (1/3) • PureScriptͰ৽ͨͳ໰୊ʹऔΓ૊Ήͱ͖͸ɺѻ͏஋ͷܕͷఆ͔ٛΒ࢝ΊΔͷ͕ Α͍ • ࠷ॳʹɺॅॴ࿥ʹؚ·ΕΔϨίʔυͷܕΛఆٛ type

    Entry = { firstName :: String , lastName :: String , address :: Address } • ͜Ε͸Entryͱ͍͏ܕಉٛޠ(type synonymɺܕγϊχϜ)ΛఆٛʢܕEntry͸౳ ߸ͷӈลͱಉ͡ܕʣ • Ϩίʔυ͸firstNameɺlastNameɺphoneͱ͍͏̏ͭͷϑΟʔϧυ͔ΒͳΔ • ೋͭͷ໊લϑΟʔϧυ͸StringܕͰɺaddressϑΟʔϧυ͸࣍εϥΠυͰఆٛ͞ ΕΔAddressܕ 47
  36. 48.

    3ষ ؔ਺ͱϨίʔυ ಠࣗͷܕͷఆٛ (2/3) type Address = { street ::

    String , city :: String , state :: String } • Ϩίʔυ͸ɺଞͷϨίʔυΛؚΉ͜ͱ͕Ͱ͖Δ 48
  37. 49.

    3ষ ؔ਺ͱϨίʔυ ಠࣗͷܕͷఆٛ (3/3) • ॅॴ࿥ͷσʔλߏ଄͸ɺ୯ʹ߲໨ͷ࿈݁Ϧετ type AddressBook = List

    Entry • List Entry͸Array Entryͱಉ͡Ͱ͸ͳ͍ • Array Entry͸ॅॴ࿥ͷ߲໨ͷ഑ྻ 49
  38. 50.

    3ষ ؔ਺ͱϨίʔυ ܕߏஙࢠͱछ (1/3) • List͸ܕߏஙࢠ(type constructorɺܕίϯετϥΫλ)ͷҰྫ • Listͦͷ΋ͷ͸ܕͰ͸ͳ͘ɺԿΒ͔ͷܕa͕͋Δͱ͖List a͕ܕ

    ʹͳΔ • ͭ·Γɺ List͸ܕҾ਺(type argument) aΛͱΓɺ৽ͨͳܕList a Λߏங͢Δ • ؔ਺ద༻ͱಉ͡Α͏ʹɺܕߏஙࢠ͸ଞͷܕʹฒ΂Δ͜ͱͰద༻͞Ε Δ • ܕList Entry͸ɺܕߏஙࢠList͕ܕEntryʹద༻͞Εͨ΋ͷ 50
  39. 51.

    3ষ ؔ਺ͱϨίʔυ ܕߏஙࢠͱछ (2/3) • (ܕ஫ऍԋࢉࢠ ::Λ࢖ͬͯ)΋͠ܕListͷ஋Λؒҧͬͯఆٛ͠Α͏ͱ͢ Δͱɺࠓ·Ͱݟͨ͜ͱͷͳ͍Α͏ͳछྨͷΤϥʔ͕දࣔ͞ΕΔ > import

    Data.List > Nil :: List In a type-annotated expression x :: t, the type t must have kind * • ͜Ε͸छΤϥʔ(kind error) • ஋͕ͦͷܕͰ۠ผ͞ΕΔͷͱಉ͡Α͏ʹɺܕ͸ͦͷछ(kind)ʹΑͬ ͯ۠ผ͞Εɺؒҧͬͨܕͷ஋͕ܕΤϥʔʹͳΔΑ͏ʹɺؒҧͬͨछ ͷܕ͸छΤϥʔΛҾ͖ى͜͢ 51
  40. 52.

    3ষ ؔ਺ͱϨίʔυ ܕߏஙࢠͱछ (3/3) • NumberͷΑ͏ͳɺ஋Λ࣋ͭ͢΂ͯͷܕͷछΛද͢*ͱݺ͹ΕΔಛผͳछ͕͋Δ • ܕߏஙࢠʹ΋छ͕͋Δ • ͨͱ͑͹ɺछ*

    -> *͸ListͷΑ͏ͳܕ͔Βܕ΁ͷؔ਺ • ͜͜ͰΤϥʔ͕ൃੜͨ͠ͷ͸ɺ஋͕छ*Ͱ͋ΔΑ͏ͳܕΛ࣋ͭͱظ଴͞Ε͍ͯ ͨͷʹɺList͸छ* -> *Λ͍࣋ͬͯΔͨΊͰ͢ɻ • PSCiͰܕͷछΛௐ΂Δʹ͸ɺ:kindίϚϯυΛ࢖༻ > :kind Number * > import Data.List > :kind List * -> * > :kind List String * 52
  41. 53.

    3ষ ؔ਺ͱϨίʔυ ॅॴ࿥ͷ߲໨ͷදࣔ (1/2) • จࣈྻͰॅॴ࿥ͷ߲໨Λදݱ͢ΔΑ͏ͳؔ਺Λॻ͘ • ܕએݴ͸ɺؔ਺ͷ໊લͱͦͷܕΛ::ه߸Ͱ۠੾ΔΑ͏ʹͯ͠ॻ͘ʢܕએݴΛܕγάω νϟͱ΋ݺͿʣ •

    ܕએݴ͸লུ͢Δ͜ͱ΋Ͱ͖Δ͕ɺυΩϡϝϯτͱͯ͠΋໾ཱͭͷͰܕએݴΛͨ͠ํ ͕Α͍ showEntry :: Entry -> String • showEntry͸Ҿ਺ͱͯ͠EntryΛऔΓStringΛฦؔ͢਺Ͱ͋Δͱ͍͏͜ͱΛɺએݴ ͍ͯ͠Δ showEntry entry = entry.lastName <> ", " <> entry.firstName <> ": " <> showAddress entry.address • ͜ͷؔ਺͸EntryϨίʔυͷ̏ͭͷϑΟʔϧυΛ࿈݁͠ɺ୯Ұͷจࣈྻʹ͢Δ • showAddressؔ਺͸ɺaddressϑΟʔϧυͷதͷϨίʔυΛจࣈྻʹม׵͢Δ 53
  42. 54.

    3ষ ؔ਺ͱϨίʔυ ॅॴ࿥ͷ߲໨ͷදࣔ (2/2) showAddress :: Address -> String showAddress

    addr = addr.street <> ", " <> addr.city <> ", " <> addr.state • ؔ਺ఆٛ͸ؔ਺ͷ໊લͰ࢝·ΓɺҾ਺໊ͷϦετ͕ଓ͘ • ؔ਺ͷ݁Ռ͸౳߸ͷޙΖʹఆٛ • ϑΟʔϧυ͸υοτʹଓ͚ͯϑΟʔϧυ໊Λॻ͘͜ͱͰࢀর͢Δ͜ ͱ͕Ͱ͖Δ • PureScriptͰ͸ɺจࣈྻ࿈݁͸JavaScriptͷΑ͏ͳ୯Ұͷϓϥεه ߸Ͱ͸ͳ͘ɺμΠΞϞϯυԋࢉࢠʢ<>ʣΛ࢖༻ 54
  43. 55.

    3ষ ؔ਺ͱϨίʔυ ͸΍Ίʹςετɺͨͼͨͼςετ (1/3) • PSCiΠϯλϥΫςΟϒϞʔυͰ͸൓ԠΛଈ࠲ʹಘΒΕΔͷͰɺࢼߦ ࡨޡΛ܁Γฦ͍ͨ͠ͱ͖ʹ޲͍͍ͯΔ • ͜ͷ࠷ॳͷؔ਺͕ਖ਼͘͠ಈ࡞͢Δ͔Λ֬ೝ͢Δ •

    ·ͣɺ͜Ε·Ͱॻ͔ΕͨίʔυΛϏϧυ $ pulp build • ࣍ʹɺPSCiΛىಈ͠ɺ͜ͷ৽͍͠ϞδϡʔϧΛΠϯϙʔτ͢ΔͨΊ ʹ:import໋ྩΛ࢖͍·͢ɻ $ pulp psci > import Data.AddressBook 55
  44. 56.

    3ষ ؔ਺ͱϨίʔυ ͸΍Ίʹςετɺͨͼͨͼςετ (2/3) • ϨίʔυϦςϥϧΛ࢖͏ͱɺ߲໨Λ࡞੒͢Δ͜ͱ͕Ͱ͖Δ • ϨίʔυϦςϥϧ͸JavaScriptͷແ໊ΦϒδΣΫτͱಉ͡Α͏ͳߏ จ •

    ϨίʔυϦςϥϧΛletࣜͰ໊લʹଋറ > let address = { street: "123 Fake St.", city: "Faketown", state: "CA" } • ͜ͷؔ਺Λaddressʹద༻ > showAddress address "123 Fake St., Faketown, CA" 56
  45. 57.

    3ষ ؔ਺ͱϨίʔυ ͸΍Ίʹςετɺͨͼͨͼςετ (3/3) • example addressΛؚΉॅॴ࿥ͷϨίʔυΛ࡞ͬͯɺshowEntry Λςετ > let

    entry = { firstName: "John", lastName: "Smith", address: address } > showEntry entry "Smith, John: 123 Fake St., Faketown, CA” 57
  46. 58.

    3ষ ؔ਺ͱϨίʔυ ॅॴ࿥ͷ࡞੒ (1/4) • ॅॴ࿥ͷૢ࡞Λࢧԉ͢Δؔ਺Λ͍͔ͭ͘ॻ͘ • ۭͷॅॴ࿥Λද͢஋ͱͯ͠ɺۭͷϦετΛ࢖͏ emptyBook ::

    AddressBook emptyBook = empty • طଘͷॅॴ࿥ʹ஋Λૠೖ͢ΔinsertEntryؔ਺ͷܕએݴ insertEntry :: Entry -> AddressBook -> AddressBook • insertEntry͸ɺ࠷ॳͷҾ਺ͱͯ͠EntryɺୈೋҾ਺ͱͯ͠ AddressBookΛऔΓɺ৽͍͠AddressBookΛฦ͢ 58
  47. 59.

    3ষ ؔ਺ͱϨίʔυ ॅॴ࿥ͷ࡞੒ (2/4) • طଘͷAddressBookΛ௚઀มߋ͠ͳ͍ • ಉ͡σʔλؚ͕·Ε͍ͯΔ৽͍͠AddressBookΛฦ͢ • AddressBook͸ෆมσʔλߏ଄(immutable

    data structure)ͷҰྫ • ͜Ε͸PureScriptʹ͓͚Δॏཁͳߟ͑ํ • มߋ͸ίʔυͷ෭࡞༻Ͱ͋ΓɺίʔυͷৼΔ෣͍ʹ͍ͭͯͷ൑அ͢ΔͷΛ೉͘͢͠ Δ • Data.ListͷConsؔ਺Λ࢖༻͢ΔͱinsertEntryΛ࣮૷Ͱ͖Δ • PSCiΛىಈ͠:typeίϚϯυΛ࢖ͬͯɺConsؔ਺ͷܕΛݟͯΈΔ $ pulp psci > import Data.List > :type Cons forall a. a -> List a -> List a 59
  48. 61.

    3ষ ؔ਺ͱϨίʔυ ॅॴ࿥ͷ࡞੒ (4/4) • EntryɺͱAddressBookʹConsΛద༻͢Δͱɺ৽͍͠ AddressBookΛಘΔ͜ͱ͕Ͱ͖Δ • insertEntryͷ࣮૷͸࣍ͷΑ͏ʹͳΔ insertEntry

    entry book = Cons entry book • ౳߸ͷࠨଆʹ͋Δ̎ͭͷҾ਺entryͱbook͕είʔϓʹಋೖ͞Ε ΔͷͰɺ͜ΕΒʹConsؔ਺Λద༻ͯ݁͠Ռͷ஋Λ࡞੒͢Δ • είʔϓʢ༗ޮൣғʣʹಋೖ͞ΕΔͱ͸ɺؔ਺ͷ࣮૷ఆ͔ٛΒࢀ রͰ͖ΔΑ͏ʹͳΔ͜ͱ 61
  49. 62.

    3ষ ؔ਺ͱϨίʔυ ΧϦʔԽ͞Εͨؔ਺ (1/5) • PureScriptͰ͸ɺؔ਺͸ৗʹͻͱͭͷҾ਺͚ͩΛऔΔ • insertEntryؔ਺͸̎ͭͷҾ਺ΛऔΔΑ͏ʹݟ͑·͕͢ɺ͜Ε͸࣮ ࡍʹ͸ΧϦʔԽ͞Εͨؔ਺(curried function)ͷҰྫ

    • insertEntryͷܕʹؚ·ΕΔ ->͸ӈ݁߹ͷԋࢉࢠͰ͋Γɺͭ·Γ ͜ͷܕ͸ίϯύΠϥʹΑͬͯ࣍ͷΑ͏ʹղऍ͞ΕΔ Entry -> (AddressBook -> AddressBook) • insertEntry͸ؔ਺Λฦؔ͢਺ • ͜ͷؔ਺͸୯ҰͷҾ਺ EntryΛऔΓɺͦΕ͔Β୯ҰͷҾ਺ AddressBookΛऔΓ৽͍͠ AddressBookΛฦ͢৽͍ؔ͠਺Λฦ͢ 62
  50. 63.

    3ষ ؔ਺ͱϨίʔυ ΧϦʔԽ͞Εͨؔ਺ (2/5) • ࠷ॳͷҾ਺͚ͩΛ༩͑ΔͱinsertEntryΛ෦෼ద༻(partial application)Ͱ͖Δ • PSCiͰ͜ͷ݁ՌͷܕΛݟͯΈΔ >

    :type insertEntry entry AddressBook -> AddressBook • ໭Γ஋ͷܕ͸ؔ਺ • ͜ͷ݁Ռͷؔ਺ʹɺ;ͨͭΊͷҾ਺Λద༻Ͱ͖Δ > :type (insertEntry entry) emptyBook AddressBook 63
  51. 64.

    3ষ ؔ਺ͱϨίʔυ ΧϦʔԽ͞Εͨؔ਺ (3/5) • ׅހ͸ෆཁͳͷͰ࣍ͷࣜ͸લͷࣜͱಉ౳ > :type insertEntry entry

    emptyBook AddressBook • ͜Ε͸ؔ਺ద༻͕ࠨ݁߹Ͱ͋ΔͨΊ • ࠓޙɺ࠷ॳͷҾ਺ΛऔΓผͷؔ਺Λฦ͢ɺΧϦʔԽ͞Εͨؔ਺Λʮ̎ Ҿ਺ͷؔ਺ʯͱදݱ͢Δ͜ͱ͕͋Δ 64
  52. 65.

    3ষ ؔ਺ͱϨίʔυ ΧϦʔԽ͞Εͨؔ਺ (4/5) • insertEntryͷఆٛ insertEntry :: Entry ->

    AddressBook -> AddressBook insertEntry entry book = Cons entry book • ࣜͷӈลʹ໌ࣔతʹׅހΛ͚ͭΔͱɺ(Cons entry) bookͱͳ Δ • insertEntry entry͸ͦͷҾ਺͕୯ʹؔ਺(Cons entry)ʹ౉ ͞ΕΔΑ͏ͳؔ਺ͳͷͰɺલͷఆٛͷ྆ล͔ΒҾ਺ bookΛ࡟আͰ ͖Δ insertEntry :: Entry -> AddressBook -> AddressBook insertEntry entry = Cons entry 65
  53. 66.

    3ষ ؔ਺ͱϨίʔυ ΧϦʔԽ͞Εͨؔ਺ (5/5) • ಉ༷ͷཧ༝Ͱ྆ล͔Βentry΋࡟আͰ͖Δ insertEntry :: Entry ->

    AddressBook -> AddressBook insertEntry = Cons • ͜ͷॲཧ͸Πʔλม׵(eta conversion)ͱݺ͹ΕɺҾ਺Λࢀর͢Δ ͜ͱͳؔ͘਺Λఆٛ͢ΔϙΠϯτϑϦʔܗࣜ(point-free form)΁ͱ ؔ਺Λॻ͖׵͑Δͷʹ࢖͑Δ • insertEntryͷ৔߹ʹ͸ɺΠʔλม׵ʹΑͬͯʮinsertEntry͸ ୯ʹϦετʹର͢ΔConsͩʯͱؔ਺ͷఆٛ͸ͱͯ΋໌֬ʹͳͬͨ • ৗʹϙΠϯτϑϦʔܗࣜͷ΄͏͕͍͍ͷ͔Ͳ͏͔ʹ͸ٞ࿦ͷ༨஍͕ ͋Δ 66
  54. 68.

    3ষ ؔ਺ͱϨίʔυ ॅॴ࿥ͷ໰͍߹Θͤ (2/6) • ͜ͷେ·͔ͳ࢓༷ʹैͬͯɺ͜ͷؔ਺ͷܕΛܭࢉ͢Δ͜ͱ͕Ͱ͖Δ • ·ͣPSCiΛىಈ͠ɺfilterؔ਺ͱheadؔ਺ͷܕΛݟΔ $ pulp

    psci > import Data.List > :type filter forall a. (a -> Boolean) -> List a -> List a > :type head forall a. List a -> Maybe a 68
  55. 69.

    3ষ ؔ਺ͱϨίʔυ ॅॴ࿥ͷ໰͍߹Θͤ (3/6) • filter͸ΧϦʔԽ͞Εͨ̎Ҿ਺ͷؔ਺ • ࠷ॳͷҾ਺͸ɺϦετͷཁૉΛऔΓBoolean஋Λ݁Ռͱͯ͠ฦؔ͢਺ • ୈ̎Ҿ਺͸ཁૉͷϦετͰɺฦΓ஋͸ผͷϦετ

    • head͸Ҿ਺ͱͯ͠ϦετΛͱΓɺMaybe aͱ͍͏ܕΛฦ͢ • Maybe a͸ܕaͷΦϓγϣφϧͳ஋ɺͭ·Γaͷ஋Λ͔࣋ͭ࣋ͨͳ͍͔ͷͲ ͪΒ͔ͷ஋Λ͓ࣔͯ͠ΓɺJavaScriptͷΑ͏ͳݴޠͰ஋͕ͳ͍͜ͱΛࣔͨ͢ Ίʹ࢖ΘΕΔnullͷܕ҆શͳ୅ସखஈΛఏڙ͢Δ • filterͱheadͷશশྔԽ͞Εͨܕ͸ɺPureScriptίϯύΠϥʹΑͬͯ࣍ͷΑ ͏ʹಛघԽ͞ΕΔ filter :: (Entry -> Boolean) -> AddressBook -> AddressBook head :: AddressBook -> Maybe Entry 69
  56. 70.

    3ষ ؔ਺ͱϨίʔυ ॅॴ࿥ͷ໰͍߹Θͤ (4/6) • ݕࡧ͢Δؔ਺ͷҾ਺ͱͯ͠੏ͱ໊લΛΛ౉͢ඞཁ͕͋Δ • filterʹ౉ؔ͢਺΋ඞཁʹͳΔ • ͜ͷؔ਺ΛfilterEntryͱݺͿ

    • filterEntry͸Entry -> Booleanͱ͍͏ܕΛ࣋ͭ • filter filterEntryͱ͍͏ؔ਺ద༻ͷࣜ͸ɺAddressBook -> AddressBookͱ͍͏ܕΛ࣋ͭ • ΋͜͠ͷؔ਺ͷ݁ՌΛheadؔ਺ʹ౉͢ͱɺܕMaybe Entryͷ݁Ռ ΛಘΔ͜ͱʹͳΓ·͢ɻ • ͜Ε·Ͱͷ͜ͱΛ·ͱΊΔͱɺfindEntryؔ਺ͷܕએݴ͸ҎԼ findEntry :: String -> String -> AddressBook -> Maybe Entry 70
  57. 71.

    3ষ ؔ਺ͱϨίʔυ ॅॴ࿥ͷ໰͍߹Θͤ (5/6) • findEntry͸ɺ੏ͱ໊લͷ2ͭͷจࣈྻɺ͓ΑͼAddressBookΛ Ҿ਺ʹͱΓɺMaybe Entryͱ͍͏ܕͷ஋Λ݁Ռͱͯ͠ฦ͢ • ݁ՌͷMaybe

    Entryͱ͍͏ܕ͸ɺ໊લ͕ॅॴ࿥Ͱൃݟ͞Εͨ৔ ߹ʹͷΈEntryͷ஋Λ࣋ͭ • findEntryͷఆٛ͸ҎԼ findEntry firstName lastName book = head $ filter filterEntry book where filterEntry :: Entry -> Boolean filterEntry entry = entry.firstName == firstName && entry.lastName == lastName 71
  58. 72.

    3ষ ؔ਺ͱϨίʔυ ॅॴ࿥ͷ໰͍߹Θͤ (6/6) • findEntry͸ɺͲͪΒ΋จࣈྻܕͰ͋ΔfirstNameͱlastNameɺ AddressBookܕͷbookͱ͍͏3ͭͷ໊લΛείʔϓʹಋೖ͢Δ • ఆٛͷӈลͰ͸filterؔ਺ͱheadؔ਺͕૊Έ߹Θͤɺ·߲ͣ໨ͷϦετΛ ϑΟϧλϦϯά͠ɺͦͷ݁Ռʹheadؔ਺Λద༻͍ͯ͠Δ

    • ਅِܕΛฦؔ͢਺filterEntry͸whereઅͷ಺෦Ͱิॿతͳؔ਺ͱͯ͠ఆٛ͞Ε ͍ͯΔ • filterEntryؔ਺͸͜ͷఆٛͷ಺෦Ͱ͸࢖༻Ͱ͖Δ͕ɺ֎෦Ͱ͸࢖༻Ͱ͖ͳ ͍ • filterEntry͸ͦΕΛแΉؔ਺ͷҾ਺ʹґଘ͢Δ͜ͱ͕Ͱ͖ɺfilterEntry͸ࢦ ఆ͞ΕͨEntryΛϑΟϧλϦϯά͢ΔͨΊʹҾ਺ firstNameͱlastNameΛ ࢖༻͍ͯ͠ΔͷͰɺfilterEntry͕findEntryͷ಺෦ʹ͋Δ͜ͱ͸ඞਢ 72
  59. 73.

    3ষ ؔ਺ͱϨίʔυ தஔͷؔ਺ద༻ (1/2) • headؔ਺͸தஔͷ$ԋࢉࢠΛ࢖ͬͯࣜfilter filterEntry bookʹ ద༻͞Ε͍ͯΔ •

    ͜Ε͸head (filter filterEntry book)ͱ͍͏௨ৗͷؔ਺ద༻ͱ ಉ͡ҙຯ • ($)͸PreludeͰఆٛ͞Ε͍ͯΔ௨ৗͷؔ਺Ͱɺఆٛ͸ҎԼ apply :: forall a b. (a -> b) -> a -> b apply f x = f x infixr 0 apply as $ • ($)͸ؔ਺ͱ஋ΛͱΓɺͦͷ஋ʹͦͷؔ਺Λద༻ • infixrΩʔϫʔυ͸ɺ($)ΛapplyͷΤΠϦΞεͱͯ͠ఆٛ͢Δͨ Ίʹ࢖ΘΕΔ 73
  60. 74.

    3ষ ؔ਺ͱϨίʔυ தஔͷؔ਺ద༻ (2/2) • ͳͥ௨ৗͷؔ਺ద༻ͷ୅ΘΓʹ$Λ࢖ͬͨͷ͔ʁ • ͦͷཧ༝͸$͕ӈ݁߹Ͱ༏ઌॱҐͷ௿͍ԋࢉࢠͰ͋ΔͨΊ • ਂ͍ೖΕࢠʹͳͬͨؔ਺ద༻ͷͨΊͷׅހΛɺ$Λ࢖͏ͱऔΓআ

    ͘͜ͱ͕Ͱ͖Δ • ͨͱ͑͹ɺ͋Δैۀһͷ্࢘ͷॅॴ͕͋Δಓ࿏Λݟ͚ͭΔɺ࣍ͷೖ Εࢠʹͳͬͨؔ਺ద༻Λߟ͑ͯΈΔ street (address (boss employee)) • $Λ࢖༻ͯ͠දݱ͢Δͱͣͬͱ؆୯ʹͳΔ street $ address $ boss employee 74
  61. 75.

    3ষ ؔ਺ͱϨίʔυ ؔ਺߹੒ (1/2) • Πʔλม׵Λ࢖͏ͱinsertEntryؔ਺Λ؆ུԽͰ͖ͨͷͱಉ͡Α͏ʹɺҾ ਺ΛΑ͘ߟ࡯͢ΔͱfindEntryͷఆٛΛ؆ུԽ͢Δ͜ͱ͕Ͱ͖Δ • Ҿ਺book͕ؔ਺filter filterEntryʹ౉͞Εɺ͜ͷద༻ͷ݁Ռ͕head

    ʹ౉͞ΕΔ͜ͱ͸ɺݴ͍͔ͨΛม͑Ε͹filter filterEntryͱheadͷ ߹੒(composition) ʹbook͕౉͞ΕΔͱ͍͏͜ͱ • PureScriptͷؔ਺߹੒ԋࢉࢠ͸<<<ͱ>>> • લऀ͸ʮٯํ޲ͷ߹੒ʯͰɺޙऀ͸ʮॱํ޲ͷ߹੒ʯ • ͍ͣΕ͔ͷԋࢉࢠΛ࢖༻ͯ͠findEntryͷӈลΛॻ͖׵͑Δ͜ͱ͕Ͱ͖ɺ ٯॱͷ߹੒Λ࢖༻͢Δͱɺӈล͸࣍ͷΑ͏ʹͳΔ head $ filter filterEntry book ! (head <<< filter filterEntry) book 75
  62. 76.

    3ষ ؔ਺ͱϨίʔυ ؔ਺߹੒ (2/2) • ͜ͷܗࣜͳΒ࠷ॳͷఆٛʹΠʔλม׵ͷٕΛద༻͢Δ͜ͱ͕Ͱ͖ɺ findEntry͸࠷ऴతʹ࣍ͷΑ͏ͳఆٛʹͳΔ findEntry firstName lastName

    book = head $ filter filterEntry book ! findEntry firstName lastName = head <<< filter filterEntry where … • ӈลΛ࣍ͷΑ͏ʹͯ͠΋ಉ͡ head $ filter filterEntry ! filter filterEntry >>> head • ͜Ε͸ʮfindEntry͸ϑΟϧλϦϯάؔ਺ͱheadؔ਺ͷ߹੒Ͱ͋Δʯ ͱ͍͏findEntryؔ਺ͷΘ͔Γ΍͍͢ఆٛ 76
  63. 77.

    3ষ ؔ਺ͱϨίʔυ ςετɺςετɺςετ…… (1/4) • PSCiΛ࢖ͬͯࢼ͢ $ pulp psci >

    import Data.AddressBook • ۭͷॅॴ࿥͔Β߲໨Λݕࡧʢۭͷ݁Ռ͕ฦͬͯ͘Δ͜ͱΛظ଴ʣ > findEntry "John" "Smith" emptyBook No type class instance was found for Data.Show.Show { firstName :: String , lastName :: String , address :: { street :: String , city :: String , state :: String } } • ܕEntryͷ஋Λจࣈྻͱͯ͠ग़ྗ͢Δํ๏ΛPSCi͕஌Βͳ͍ͱ͍͏ҙຯͷΤϥʔ 77
  64. 78.

    3ষ ؔ਺ͱϨίʔυ ςετɺςετɺςετ…… (2/4) • findEntryͷฦΓ஋ͷܕͷMaybe Entry͸ख࡞ۀͰจࣈྻʹม׵ ͢Δ͜ͱ͕Ͱ͖Δ • showEntryؔ਺͸EntryܕͷҾ਺Λظ଴͍ͯ͠Δ͕ɺfindEntry

    ͷฦΓ஋͸Maybe Entryܕͷ஋ • Φϓγϣφϧͳ஋ͷதʹ߲໨ͷ஋͕ଘࡏ͢Ε͹showEntryؔ਺Λ ద༻͠ɺଘࡏ͠ͳ͚Ε͹ଘࡏ͠ͳ͍ͱ͍͏஋Λͦͷ··఻೻͠ͳ͚ Ε͹ͳΒͳ͍ • PreludeϞδϡʔϧ͕ఏڙ͍ͯ͠Δmapԋࢉࢠ͕ɺMaybeͷΑ͏ͳ ద੾ͳܕߏஙࢠ·Ͱؔ਺Λʮ্࣋ͪ͛Δʯ 78
  65. 79.

    3ষ ؔ਺ͱϨίʔυ ςετɺςετɺςετ…… (3/4) > import Prelude > map showEntry

    (findEntry "John" "Smith" emptyBook) Nothing • ͜ͷฦΓ஋ Nothing͸ɺΦϓγϣφϧͳฦΓ஋ʹ஋ؚ͕·Ε͍ͯͳ ͍͜ͱΛ͍ࣔͯ͠Δ • ΋ͬͱ࢖͍΍͘͢͢ΔͨΊʹɺEntryΛจࣈྻͱͯ͠ग़ྗ͢ΔΑ͏ ͳؔ਺Λఆٛ͢Δ͜ͱ΋Ͱ͖Δ > let printEntry firstName lastName book = map showEntry (findEntry firstName lastName book) 79
  66. 80.

    3ষ ؔ਺ͱϨίʔυ ςετɺςετɺςετ…… (4/4) • ۭͰͳ͍ॅॴ࿥Λ࡞੒ͯ͠΋͏Ұ౓ࢼ͢ • ઌ΄Ͳͷ߲໨ͷྫΛ࠶ར༻ > let

    book1 = insertEntry entry emptyBook > printEntry "John" "Smith" book1 Just ("Smith, John: 123 Fake St., Faketown, CA”) 80
  67. 81.

    3ষ ؔ਺ͱϨίʔυ ԋश 1. ʢ؆୯ʣfindEntryؔ਺ͷఆٛͷओͳ෦෼ࣜͷܕΛॻ͖Լ͠ɺfindEntryؔ਺ʹ ͍ͭͯΑ͘ཧղ͍ͯ͠Δ͔ࢼͯ͠Έ·͠ΐ͏ɻͨͱ͑͹ɺfindEntryͷఆٛͷͳ͔ ʹ͋Δheadؔ਺ͷܕ͸List Entry -> Maybe

    EntryͱಛघԽ͞Ε͍ͯ·͢ɻ 2. ʢ΍΍೉͍͠ʣ findEntryͷطଘͷίʔυΛ࠶ར༻͠ɺ༩͑ΒΕͨॅॴ͔Β EntryΛݕࡧ͢Δؔ਺Λॻ͍ͯΈ·͠ΐ͏ɻ·ͨɺPSCiͰ࣮૷ͨؔ͠਺Λςετ͠ ͯΈ·͠ΐ͏ɻ 3. ʢ΍΍೉͍͠ʣ ࢦఆ͞Ε໊ͨલ͕AddressBookʹଘࡏ͢Δ͔Ͳ͏͔Λௐ΂ͯਅِ ஋Ͱฦؔ͢਺Λॻ͍ͯΈ·͠ΐ͏ɻώϯτɿ Ϧετ͕ۭ͔Ͳ͏͔Λௐ΂Δ Data.List.nullؔ਺ͷܕΛPSCiͰௐ΂ͯΈͯΈ·͠ΐ͏ɻ 4. ʢ೉͍͠ʣ ੏໊͕ॏෳ͍ͯ͠Δ߲໨Λॅॴ࿥͔Β࡟আ͢Δؔ਺ removeDuplicatesΛॻ͍ͯΈ·͠ΐ͏ɻώϯτɿ ஋Ͳ͏͠ͷ౳ՁੑΛఆٛ͢Δ ड़ޠؔ਺ʹج͍ͮͯϦετ͔ΒॏෳཁૉΛ࡟আ͢Δؔ਺List.nubByͷܕΛɺPSCi Λ࢖༻ͯ͠ௐ΂ͯΈ·͠ΐ͏ɻ 81
  68. 82.

    3ষ ؔ਺ͱϨίʔυ ·ͱΊ ͜ͷষͰ͸ɺؔ਺ܕϓϩάϥϛϯάͷ৽͍֓͠೦Λ͍͔ͭ͘ಋೖͨ͠ • ΠϯλϥΫςΟϒϞʔυPSCiΛ࢖༻ͯؔ͠਺Λௐ΂ͨΓࢥ͍͍ͭͨ ͜ͱΛࢼ͢ํ๏ • ݕূ΍࣮૷ͷಓ۩ͱͯ͠ͷܕͷ໾ׂ •

    ଟҾ਺ؔ਺Λදݱ͢ΔɺΧϦʔԽ͞Εͨؔ਺ͷ࢖༻ • ؔ਺߹੒Ͱখ͞ͳ෦඼Λ૊Έ߹ΘͤͯͷϓϩάϥϜͷߏங • whereઅΛར༻ͨ͠ίʔυͷߏ଄Խ • MaybeܕΛ࢖༻ͯ͠null஋Λճආ͢Δํ๏ • Πʔλม׵΍ؔ਺߹੒ͷΑ͏ͳख๏Λར༻ͨ͠ɺΑΓΘ͔Γ΍͍͢ ίʔυ΁ͷ࠶ߏ੒ 82