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

Haskell入門ハンズオン

Aruneko
July 07, 2018

 Haskell入門ハンズオン

オープンソースカンファレンス2018 Hokkaido (#osc18do) で発表したHaksell入門に関するハンズオンの資料です

Aruneko

July 07, 2018
Tweet

More Decks by Aruneko

Other Decks in Programming

Transcript

  1. )BTLFMMೖ໳ϋϯζΦϯ
    ʙ3&1-Ͱ࢝ΊΔ)BTLFMMੜ׆ʙ
    "SVOFLP!)BTLFMMKQ

    View full-size slide

  2. ࣗݾ঺հ
    w !BSVOFLP
    w Ұൠࣾஂ๏ਓ-0$"-ֶੜ෦
    w ߴߍੜ͙Β͍ͷ࣌ʹ)BTLFMMʹग़ձͬͯ͠·ͬͨ
    w )BTLFMMKQͷ4MBDLʹજ෬த

    View full-size slide

  3. )BTLFMMKQͷ͝঺հ
    w ೔ຊ)BTLFMMϢʔβʔάϧʔϓ
    w ೔ຊʹ͓͚Δ)BTLFMMͷීٴ׆ಈͱར༻ऀͷαϙʔτΛ࣮ࢪ
    w 4MBDL΋͋ΔͷͰͥͻ͝ࢀՃ͍ͩ͘͞ʂʂ

    View full-size slide

  4. શମͷྲྀΕ

    View full-size slide

  5. ໨ඪ
    w ԿΒ͔ͷݴޠΛ΍ͬͨ͜ͱ͕͋Δਓ͕
    w ͪΐͬͱ͚ͩͰ΋)BTLFMMʹ਌͠ΈΛ࣋ͯΔΑ͏ʹͳΔʂ

    View full-size slide

  6. ຊ೔ͷϝχϡʔ
    )BTLFMMͷઆ໌
    ؀ڥߏஙʹ͍ͭͯ
    3&1-Ͱ༡Ϳ
    ࿅श໰୊৭ʑ

    View full-size slide

  7. ࢀߟจݙ
    w ͍͢͝)BTLFMMͨͷֶ͘͠΅͏
    w .JSBO-JQPWB㶜Bஶ
    w ాதӳߦ༁
    w ଜओਸߦ༁
    w )BTLFMMͷΤοηϯε͕٧·ͬͨຊͰ͢ʂ

    View full-size slide

  8. )BTLFMMͬͯͲΜͳݴޠʁ

    View full-size slide

  9. )BTLFMMͬͯͲΜͳݴޠʁ
    w ʮ७ਮؔ਺ܕϓϩάϥϛϯάݴޠʯ
    w ७ਮ
    w ࡞༻ͱ෭࡞༻͕෼཭͞Ε͍ͯΔঢ়ଶ
    w ࢀরಁաੑ͕อূ͞Ε͓ͯΓɺಉ͡Ҿ਺Λ༩͑ͨؔ਺͸͍ͭݺΜͰ΋ಉ݁͡Ռ
    Λฦ͢
    w ؔ਺ܕϓϩάϥϛϯά
    w ϓϩάϥϜશମΛؔ਺ͷ૊Έ߹ΘͤͰهड़͢ΔϓϩάϥϛϯάελΠϧͷ͜ͱ

    View full-size slide

  10. )BTLFMMͬͯͲΜͳݴޠʁ
    w σϑΥϧτͰ஗ԆධՁ
    w ஋͕ਅʹඞཁʹͳΔ·ͰධՁ͞Εͳ͍
    w ৔߹ʹΑͬͯ͸ϝϦοτͰɺ৔߹ʹΑͬͯ͸σϝϦοτ
    w ڧ͍੩తܕ෇͚
    w ͍͍ͨͯͷ৔߹ܕਪ࿦ͷ͓͔͛ͰܕΛ໌ࣔ͢Δඞཁ͸ແ͍
    w Ͱ΋ॻ͘ͱ͖͸ܕΛҙࣝͭͭ͠ॻ͘ͱॻ͖΍͍͢
    w ॲཧͷࣦഊ΍*0ͳͲ΋ܕͰද͢

    View full-size slide

  11. 4UBDLΛ࢖͏
    w )BTLFMM؀ڥ͸ʮ4UBDLʯΛ࢖ͬͯߏங
    w +BWBͷ.BWFO΍4DBMBͷTCUʹ͋ͨΔϏϧυπʔϧ
    w )BTLFMMίϯύΠϥͷσϑΝΫτελϯμʔυͰ͋Δ

    ()$ͷ҆ఆ൛͕Πϯετʔϧ͞ΕΔ
    w ϓϩδΣΫτ͝ͱʹύοέʔδͷ؅ཧ͕Մೳ
    w ͨͩ͠()$ͷ༰ྔ͕େ͖͍ͷͰɺࠓճ͸঺հ͚ͩ

    View full-size slide

  12. 4UBDLͷΠϯετʔϧ
    w 6OJYܥ04Ͱ͋Ε͹ɺΠϯετʔϧ͸ҎԼͷίϚϯυҰൃͰऴྃ
    w ৄࡉ͸ެࣜαΠτΛ͝ཡ͍ͩ͘͞
    w IUUQTEPDTIBTLFMMTUBDLPSHFOTUBCMF3&"%.&
    $ curl -sSL https://get.haskellstack.org/ | sh

    View full-size slide

  13. 4UBDLΛ࢖͏
    w ॳճ͸·ͣΞοϓσʔτΛ͠ɺ4UBDLBHF͔Β࠷৽ͷ-54Λऔಘ
    w 4UBDLBHF͸)BTLFMMύοέʔδͷ҆ఆ൛όʔδϣϯΛूΊͨϦϙδτϦ
    w Ξοϓσʔτ͕Ͱ͖ͨΒ3&1- ()$J
    Λىಈ
    $ stack update
    $ stack ghci

    View full-size slide

  14. ΦϯϥΠϯ3&1-
    w ࠓճ͸4UBDL()$Jͷ୅ΘΓʹΦϯϥΠϯ3&1-ͷSFQMJUΛར༻
    w IUUQTSFQMJUMBOHVBHFTIBTLFMM
    w ը໘ࠨ͕ΤσΟλɺӈ͕()$J

    View full-size slide

  15. ͜ͷηΫγϣϯͰ΍Δ͜ͱ
    w ()$Jʹ؆୯ͳࣜΛଧͪࠐΜͰి୎୅ΘΓʹ࢖͑ΔΑ͏ʹͳΔ
    w #PPMԋࢉ͕Ͱ͖Δ

    View full-size slide

  16. ()$JͰి୎
    w Α͋͘Δதஔԋࢉࢠ͕ར༻Մೳ
    w

    w )BTLFMMతʹ͸தஔؔ਺ͱݺͼ·͢
    w ΧοίͳͲ΋ͦͷ··
    w ͨͩ͠ϚΠφεͷ஋͸ׅހΛ෇͚ͯ໌ࣔ
    w ಛఆͷ৚݅ͰύʔεΤϥʔʹͳΓ·͢
    > 1 + 1
    2
    > (2 + 4) / 2
    3.0
    > 2 * 10 / 5
    4.0
    > 10 - 100
    -90
    > -10 + 20
    10
    > 20 - (-10)
    30
    > 20 - -10
    Precedence parsing error

    View full-size slide

  17. ()$JͰ#PPMԋࢉ
    w ଞͷݴޠͱ͍͍ͩͨҰॹ
    w ൱ఆ͚ͩ஫ҙʂʂ
    > 'a' == 'a'
    True
    > 1 /= 1
    False
    > True && False
    False
    > False || True
    True
    > not True
    False

    View full-size slide

  18. ͜͜·Ͱͷ·ͱΊ
    w ଞͷݴޠͱ΄΅มΘΒͳ͍࢛ଇԋࢉ͕Մೳ
    w #PPMԋࢉ΋΄΅ಉ༷͚ͩͲɺ൱ఆͷܗʹ஫ҙ

    View full-size slide

  19. ؔ਺Λ࢖͏ɾ࡞Δ

    View full-size slide

  20. ͜ͷηΫγϣϯͰ΍Δ͜ͱ
    w )BTLFMMಛ༗ͷؔ਺ݺͼग़͠ΛֶͿ
    w தஔؔ਺ͱલஔؔ਺ͷม׵ΛֶͿ
    w ݁߹ॱংΛֶͿ

    View full-size slide

  21. ؔ਺ͷݺͼํ

    w Ҿ਺Λεϖʔε۠੾ΓͰࢦఆ͢Δ͚ͩ
    w Ҿ਺ؔ਺ͷ৔߹͸όοΫΫΥʔτͰғΜͰதஔܗࣜʹ΋Ͱ͖Δ
    w ٯʹதஔؔ਺͸ׅހͰғΉͱҾ਺ؔ਺ԽͰ͖Δ
    > mod 10 3
    1
    > 10 `mod` 3
    1
    > (+) 1 2
    3

    View full-size slide

  22. ؔ਺ͷݺͼํ

    w ݁߹ॱং͸ؔ਺ద༻͕࠷ڧͳͷͰదٓΧοίΛ࢖͏
    w ͔ͦ͜ΒޙΖશ෦ΛׅހʹೖΕ͍ͨ৔߹͸ʮʯ͕ศར
    > sin (pi / 2)
    1.0
    > sin $ pi / 2
    1.0

    View full-size slide

  23. ܭࢉ݁Ռͷอଘ
    w ()$JͰ͸ɺΠίʔϧΛ࢖ͬͯద౰ͳม਺ʹ஋Λଋറ͢Δ͜ͱ͕Մೳ
    w ()$J͡Όͳ͍ͱ͜ΖͰ͸ͪΐͬͱҧ͏ͷͰ஫ҙ
    > hoge = 1
    > hoge
    1
    > fuga = sin $ pi / 2
    > fuga
    1.0

    View full-size slide

  24. ؔ਺Λ࡞Δ
    w Ҿ਺Λεϖʔε۠੾ΓͰॻ͍ͯ͋͛Ε͹0,
    w )BTLFMM͸ࣜࢦ޲ͰͲΜͳؔ਺΋ৗʹ஋Λฦ͢ͷͰSFUVSO͸ෆཁ
    w ෆཁͱ͍͏͔ͦ΋ͦ΋SFUVSOΛॻ͚ͳ͍
    w ࡾฏํͷఆཧΛॻ͍ͯΈΔ
    > calcDistance x1 y1 x2 y2 = sqrt $ (x1 - x2) ^ 2 + (y1 - y2) ^ 2
    > calcDistance 0 0 1 1
    1.4142135623730951
    > calcDistance 0 0 1 (sqrt 3)
    1.9999999999999998
    a2 + b2 = c2

    View full-size slide

  25. ͜͜·Ͱͷ·ͱΊ
    w ؔ਺ݺͼग़͠͸Ҿ਺Λεϖʔε۠੾ΓͰ
    w Χοί
    ͱAόοΫΫΥʔτAͰલஔͱதஔʹม׵
    w ݁߹ॱং͸ؔ਺͕࠷ڧ
    w దٓΧοί΍Λ࢖ͬͯ༏ઌॱҐΛ੍ޚ
    w ؔ਺ఆٛ΋Ҿ਺Λεϖʔε۠੾ΓͰ
    w ͨͩ͠SFUVSO͸͍Βͳ͍

    View full-size slide

  26. ϦετͰ༡Ϳ

    View full-size slide

  27. ͜ͷηΫγϣϯͰ΍Δ͜ͱ
    w Ϧετͷఆٛํ๏
    w ϨϯδΛ࢖ͬͨϦετͷҰׅੜ੒
    w Ϧετͷܨ͗ํ
    w Ϧετૢ࡞ؔ਺
    w ແݶϦετ

    View full-size slide

  28. ϦετΛ࡞Δ
    w Α͘ݟΔײ͡ͷϦςϥϧͰॻ͚Δ
    w ൣғ Ϩϯδ
    ੜ੒΋Մೳ ॱ൪͕͋Δ΋ͷͳΒԿͰ΋0,

    w ॳظ஋ͱ൪໨ͷ஋ΛΧϯϚ۠੾ΓͰॻ͚͹౳ࠩ਺ྻ΋0,
    > l = [1, 3, 5, 7, 9]
    > l
    [1,3,5,7,9]
    > [1..10]
    [1,2,3,4,5,6,7,8,9,10]
    > ['a'..'g']
    "abcdefg"
    > [1,4..20]
    [1,4,7,10,13,16,19]

    View full-size slide

  29. ϦετΛܨ͙
    w ϦετͱϦετΛܨ͙ʹ͸Λ࢖͏
    w ୯ํ޲ϦετͷͨΊڊେϦετʹܨ͝͏ͱ͢Δͱஶ͘͠஗͍ͷͰ஫ҙ
    w ઌ಄ʹͭ෇͚଍͍ͨ͠ͱ͖͸ίϩϯΛ࢖͏
    w ຤ඌʹ͸෇͚଍ͤͳ͍ͷͰ஫ҙ
    Prelude> [1..5] ++ [4..10]
    [1,2,3,4,5,4,5,6,7,8,9,10]
    Prelude> 5:[6..10]
    [5,6,7,8,9,10]

    View full-size slide

  30. Ϧετૢ࡞ؔ਺
    w ઌ಄ΛऔΓग़͢
    w ઌ಄Ҏ֎ΛऔΓग़͢
    w ຤ඌҎ֎ΛऔΓग़͢
    w ຤ඌΛऔΓग़͢
    > head [1..5]
    1
    > tail [1..5]
    [2,3,4,5]
    > init [1..5]
    [1,2,3,4]
    > last [1..5]
    5

    View full-size slide

  31. ແݶϦετ
    w )BTLFMM͸σϑΥϧτͰ஗ԆධՁͳͷͰແݶϦετ͕࡞੒Մೳ
    w Ϩϯδͷ຤ඌΛল͘ͱແݶϦετʹͳΔ
    w ద౰ʹʮ$USM$ʯͰࢭΊ͍ͯͩ͘͞
    w Ͳ͔͜ͰධՁ͕Ұҙʹఆ·ΔΑ͏ͳؔ਺ͱ૊Έ߹ΘͤΔ͜ͱ΋Մೳ
    > [1..]
    [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,……
    > head [1..]
    1

    View full-size slide

  32. ͜͜·Ͱͷ·ͱΊ
    w ͋Γ͕ͪͳํ๏ͰϦετΛఆٛՄೳ
    w ϨϯδͰϦετΛҰׅੜ੒
    w Ϧετಉ࢜͸Ͱɺઌ಄ʹ͚ͭͩͳΒͰܨ͙
    w Ϧετૢ࡞ؔ਺Λศརʹ࢖ͬͯ஋ΛऔΓग़͢
    w Ϩϯδ͸ແݶϦετ΋ੜ੒Մೳ

    View full-size slide

  33. ܕͱΊ͙Δ)BTLFMMੈք

    View full-size slide

  34. ͜ͷηΫγϣϯͰ΍Δ͜ͱ
    w ܕͷௐ΂ํ
    w ܕͷදهํ๏
    w ܕม਺
    w தஔؔ਺ͷܕ
    w ܕΫϥε

    View full-size slide

  35. ܕΛௐ΂Δ
    w )BTLFMM͸ͱʹ͔͘ܕΛҙࣝ͢Δͱॻ͖΍͍͢
    w ()$JͰܕΛௐ΂Δʹ͸ʮUʯίϚϯυΛར༻
    > :t 'a'
    'a' :: Char
    > :t False
    False :: Bool

    View full-size slide

  36. ܕͷදهͱม਺
    w )BTLFMMͰ͸ԾҾ਺໊ͱܕ͸ผʑʹఆٛ
    w ܕఆٛ͸Ҿ਺ͷܕͱฦΓ஋ͷܕΛಛʹ۠ผͤͣͰ۠੾ͬͯఆٛ
    w IFBE΍UBJMͷܕΛௐ΂Δͱग़ͯ͘ΔzBz͕ܕม਺
    w Ҿ਺ͱฦΓ஋Ͱܕ͸ಉ͡Ͱ͋ͬͯཉ͍͚͠ͲͲΜͳܕͰ΋0,
    > :t head
    head :: [a] -> a
    > :t tail
    tail :: [a] -> [a]

    View full-size slide

  37. தஔؔ਺ͷܕΛௐ΂Δ
    w தஔؔ਺ͷܕΛௐ΂Δͱ͖͸ΧοίͰ͘͘Δ
    w ଍͠ࢉͷྫ
    w ͜ͷ͸ԿͩΖ͏ʁ
    > :t (+)
    (+) :: Num a => a -> a -> a

    View full-size slide

  38. ܕΫϥεͱܕม਺
    w /VN͸਺஋શൠΛද͢ܕΫϥε
    w ܕΛ෼ྨ͢ΔͨΊͷ࢓૊Έ
    w /VNB͸ʮB͸/VNͷΠϯελϯεʯͱ͍͏੍໿Λҙຯ͢Δ
    w ٯʹݴ͏ͱʮB͸/VNͳΒͳΜͰ΋͍͍ʯͱ΋ղऍՄೳ
    w /VNͷΠϯελϯεͱͯ͠*OU΍%PVCMF͕ఆٛ͞Ε͍ͯΔ
    (+) :: Num a => a -> a -> a

    View full-size slide

  39. ͜͜·Ͱͷ·ͱΊ
    w UίϚϯυͰܕ͕ௐ΂ΒΕΔ
    w ԾҾ਺ͱܕ͸ผʑʹఆٛ
    w ͰԾҾ਺ͷܕͱฦΓ஋ͷܕΛ۠੾ͬͯॻ͘
    w ܕม਺Λ࢖ͬͯ͏·͘ந৅Խ
    w தஔؔ਺ͷܕΛௐ΂Δͱ͖͸ Χοί
    Λ࢖͏
    w ܕΛ·ͱΊΔͨΊʹܕΫϥε͕࢖͑Δ

    View full-size slide

  40. ؔ਺ͷਂ۷Γ

    View full-size slide

  41. ͜ͷηΫγϣϯͰ΍Δ͜ͱ
    w ΧϦʔԽ
    w ߴ֊ؔ਺
    w ߹੒ؔ਺

    View full-size slide

  42. ؔ਺ͷΧϦʔԽ
    w )BTLFMMͷؔ਺͸σϑΥϧτͰΧϦʔԽ͞ΕΔ
    w Ҿ਺Λऔͬͯʮ࢒ΓͷҾ਺ΛऔͬͯฦΓ஋Λฦؔ͢਺ʯΛฦ͢
    w ؔ਺ͷ෦෼ద༻͕ՄೳʹͳΔ
    > :t gcd
    gcd :: Integral a => a -> a -> a
    > gcdOfFiveAnd = gcd 5
    > :t gcdOfFiveAnd
    gcdOfFiveAnd :: Integral a => a -> a
    > gcdOfFiveAnd 13
    1

    View full-size slide

  43. ߴ֊ؔ਺
    w ؔ਺ΛҾ਺ʹऔΔؔ਺Λߴ֊ؔ਺ͱݺͿ
    w Ҿ਺ʹؔ਺Λ౉͢ͱ͖͸ϥϜμࣜΛ࢖͏
    w Ͱ΋ΧϦʔԽ͞ΕΔ͜ͱΛࢥ͍ग़͢ͱ΋ͬͱศར
    > :t map
    map :: (a -> b) -> [a] -> [b]
    > map (\x -> mod 10 x) [1, 2, 3]
    [0,0,1]
    > map (mod 10) [1, 2, 3]
    [0,0,1]

    View full-size slide

  44. ߹੒ؔ਺
    w ਺ֶͷ࣌ؒʹ΍ͬͨ͋ͷҾ਺ؔ਺ͷ߹੒ؔ਺͸ʮʯͰදݱ
    w ଟҾ਺ؔ਺͸෦෼ద༻ͯ͠Ҿ਺ؔ਺ʹ͢Ε͹߹੒Մೳ
    g(f(x)) = (g ∘ f)(x)
    > cos . sin $ pi
    1.0
    cos(sin(x)) = (cos ∘ sin)(x)
    > sum . map (+ 1) . filter (> 5) $ [3, 4, 5, 6, 7]
    15

    View full-size slide

  45. ͜͜·Ͱͷ·ͱΊ
    w )BTLFMMͷؔ਺͸σϑΥϧτͰΧϦʔԽ͞Ε͍ͯΔ
    w ؔ਺ΛҾ਺ʹऔΔؔ਺͕ߴ֊ؔ਺
    w lzͰؔ਺͕߹੒Մೳ

    View full-size slide

  46. λϓϧͰ༡Ϳ

    View full-size slide

  47. ͜ͷηΫγϣϯͰ΍Δ͜ͱ
    w λϓϧͱ͸ʁ
    w Ϧετ͔ΒλϓϧΛੜ੒
    w ϥϜμࣜͰλϓϧΛ࢖͏ʹ͸

    View full-size slide

  48. λϓϧͱ͸ʁ
    w λϓϧ͸ݻఆ௕ͷ೚ҙͷ஋ͷ૊
    w Ϧετ͸୯ҰܕͰ͔͠࡞Εͳ͍͕λϓϧ͸ෳ਺ͷܕ͔Β࡞੒Մೳ
    > (1, 2)
    > ("Hello", 5)
    > (1, 2.5, [1..3])

    View full-size slide

  49. Ϧετ͔ΒλϓϧΛ࡞Δ
    w [JQͰͭͷϦετ͔Βཁૉͷλϓϧ͕࡞੒Մೳ
    w ௕͞͸୹͍ํʹ߹ΘͤΒΕΔ
    > zip [1..5] ['a'..'z']
    [(1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e')]

    View full-size slide

  50. ϥϜμࣜͰλϓϧΛड͚औΔ
    w λϓϧ͸Ҿ਺ʹऔΔͱ͖ʹύλʔϯϚονͰ෼ղՄೳ
    w Ͱ΋͜ͷ৔߹͸[JQ8JUIͨ͠΄͏͕؆ܿ
    > map (\ (x, y) -> x + y) $ zip [1..10] [1..10]
    [2,4,6,8,10,12,14,16,18,20]
    > zipWith (+) [1..10] [1..10]
    [2,4,6,8,10,12,14,16,18,20]

    View full-size slide

  51. ͜͜·Ͱͷ·ͱΊ
    w ෳ਺ͷ஋ͷ૊͕λϓϧ
    w [JQͰϦετ͔Βλϓϧ͕࡞ΕΔ
    w ϥϜμࣜͰλϓϧΛҾ਺ʹऔΔʹ͸ύλʔϯϚονΛ࢖͏
    w ৔߹ʹΑͬͯ͸[JQ8JUIͰָΛ͠Α͏

    View full-size slide

  52. ࿅श໰୊

    View full-size slide

  53. ࿅श໰୊

    w ͔Β·Ͱͷࣗવ਺ͷ͏ͪɺۮ਺ͷ࿨Λܭࢉ͠Α͏
    w ώϯτʣ
    w ۮ਺͔Ͳ͏͔͸FWFOؔ਺Ͱ൑ఆ
    w ʹͳΕ͹ਖ਼ղ

    View full-size slide

  54. ࿅श໰୊

    w ະຬͷ਺Ͱɺ͔ͷഒ਺ʹͳ͍ͬͯΔ਺ͷ߹ܭΛٻΊΑ͏
    w 1SPKFDU&VMFS1SPCMFNΑΓ
    w ͕ग़Ε͹ਖ਼ղ

    View full-size slide

  55. ࿅श໰୊

    w ࠷ॳͷݸͷࣗવ਺ʹ͓͚Δೋ৐࿨͸
    w ࠷ॳͷݸͷࣗવ਺ʹ͓͚Δ࿨ͷೋ৐͸
    w ͜ΕΒͷࠩ͸
    w ಉ༷ʹɺ࠷ॳͷݸͷࣗવ਺ʹ͓͚Δೋ৐࿨ͱ࿨ͷೋ৐ͷࠩΛٻΊΑ͏
    w 1SPKFDU&VMFS1SPCMFNΑΓ
    12 + 22 + ⋯ + 102 = 385
    (1 + 2 + ⋯ + 10)2 = 3025
    3025 − 385 = 2640

    View full-size slide

  56. ͓ΘΓʹ
    w ͪΐͬͱ͚ͩͰ΋)BTLFMMָ͠Ί·͔ͨ͠ʁ
    w ΋ͬͱ஌Γͨ͘ͳͬͨΒʮ͍͢͝)BTLFMMͨͷֶ͘͠΅͏ʯΛͥͻ
    w ͪΐͬͱهड़͕ݹ͍Օॴ͕͋ΔͷͰɺͪ͜Βͷهࣄ΋Ͳ͏ͧ
    w ೥ʹʮ͍͢͝)BTLFMMͨͷֶ͘͠΅͏ʯΛಡΉ
    w IUUQTHPPHMILK&$S

    View full-size slide