Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Functional Programming in Frontend Elm編
Search
mikesorae
December 20, 2019
Programming
1
110
Functional Programming in Frontend Elm編
フロントエンドで関数型プログラミングをやりたい資料のElm編です。
Elmの概要やPros/Cons等を紹介します。
mikesorae
December 20, 2019
Tweet
Share
More Decks by mikesorae
See All by mikesorae
Reactで学ぶUIコンポーネントデザイン / UI Component Design with React
mikesorae
1
3.3k
Other Decks in Programming
See All in Programming
MySQL初心者が311個のカラムにNot NULL制約を追加していってALTER TABLEについて学んだ話
hatsu38
2
140
リアーキテクチャの現場で向き合う 既存サービスの読み解きと設計判断
ymiyamu
0
110
SwiftDataのカスタムデータストアを試してみた
1mash0
0
150
iOSアプリで測る!名古屋駅までの 方向と距離
ryunakayama
0
160
KANNA Android の技術的課題と取り組み
watabee
1
510
一緒に働きたくなるプログラマの思想 #QiitaConference
mu_zaru
81
21k
Browser and UI #2 HTML/ARIA
ken7253
2
180
“技術カンファレンスで何か変わる?” ──RubyKaigi後の自分とチームを振り返る
ssagara00
0
110
20250429 - CNTUG Meetup #67 / DevOps Taiwan Meetup #69 - Deep Dive into Tetragon: Building Runtime Security and Observability with eBPF
tico88612
0
180
音声プラットフォームのアーキテクチャ変遷から学ぶ、クラウドネイティブなバッチ処理 (20250422_CNDS2025_Batch_Architecture)
thousanda
0
420
UMAPをざっくりと理解 / Overview of UMAP
kaityo256
PRO
3
1.5k
ぽちぽち選択するだけでOSSを読めるVSCode拡張機能
ymbigo
14
6.3k
Featured
See All Featured
Adopting Sorbet at Scale
ufuk
76
9.4k
GraphQLの誤解/rethinking-graphql
sonatard
71
11k
Practical Orchestrator
shlominoach
187
11k
Building a Modern Day E-commerce SEO Strategy
aleyda
40
7.3k
How to train your dragon (web standard)
notwaldorf
91
6k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
30
2.4k
Building Adaptive Systems
keathley
41
2.5k
Producing Creativity
orderedlist
PRO
344
40k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
13
840
Java REST API Framework Comparison - PWX 2021
mraible
31
8.6k
The Language of Interfaces
destraynor
158
25k
Optimizing for Happiness
mojombo
378
70k
Transcript
Functional Programming in Frontend Elmฤ @mikesorae
ϑϩϯτΤϯυͷͭΒΈ ! ঢ়ଶཧ ◦ ϦονUIڥͰը໘্ʹ༷ʑͳঢ়ଶ͕ෳಉ࣌ʹଘࡏ͢Δ ! ඇಉظॲཧ ◦ ಛʹSPAͰϑϩϯτΤϯυΞϓϦέʔγϣϯ͔ΒόοΫΤϯυͷAPIΛݺͼग़ͯ͠λεΫΛ ࣮ݱ͢ΔͨΊɺฒߦͯ͠ෳͷඇಉظॲཧ͕ಈ͍͍ͯΔ͜ͱ͕ଟ͍
Single State, Unidirectional Data FlowͷΑ͏ͳΞʔΩςΫνϟͱ ܧଓϞφυAlgebraic EffectsͳͲͷFPతΞϓϩʔνʹΑͬͯ ෳࡶੑΛԼ͛ΔऔΓΈ͕૿͖͑ͯͨ ↓ ͔ͤͬ͘ͳͷͰɺͬͱؔܕ͕ॻ͖͍͢ݴޠͰॻ͖͍ͨʂ
FP͚AltJS Elm Reason Scala.js PureScript ७ਮؔܕݴޠɻ)BTLFMMϥΠΫɻܰྔɻ ७ਮؔܕݴޠɻ)BTLFMMϥΠΫɻͭΑ͍ɻ ؔܕ ΦϒδΣΫτࢦɻ0$BNMϕʔεɻ 'BDFCPPLͰ3FBDU͑Δɻ
ؔܕ ΦϒδΣΫτࢦɻΈΜͳͬͯΔɻ
Elmͷ֓ཁ
Elmͱ ! HaskellϥΠΫͳ७ਮؔܕݴޠͱɺReduxͷݩͱͳͬͨUnidirectional Data FlowΞʔΩςΫνϟ(The Elm Architecture => TEA)͕Ұମͱͳͬͨͷ !
Ұൠతͳ७ਮؔܕݴޠ͕࣋ͭෳࡶͳػߏΛࣺͯɺγϯϓϧɾ࣮༻ʹدͤͯ ͍Δ
ElmΞʔΩςΫνϟ ෭࡞༻ͯ͢TEA͕͚ෛ͏ͨΊɺ࣮ߦ࣌ྫ֎͕ى͖ʹ͍͘
ΧϯλʔΞϓϦͷαϯϓϧίʔυ type alias Model = { count : Int }
initialModel : Model initialModel = { count = 0 } type Msg = Increment | Decrement update : Msg -> Model -> Model update msg model = case msg of Increment -> { model | count = model.count + 1 } Decrement -> { model | count = model.count - 1 } view : Model -> Html Msg view model = div [] [ button [ onClick Increment ] [ text "+1" ] , div [] [ text <| String.fromInt model.count ] , button [ onClick Decrement ] [ text "-1" ] ] main : Program () Model Msg main = Browser.sandbox { init = initialModel , view = view , update = update }
ΧϯλʔΞϓϦͷαϯϓϧίʔυ type alias Model = { count : Int }
initialModel : Model initialModel = { count = 0 } type Msg = Increment | Decrement update : Msg -> Model -> Model update msg model = case msg of Increment -> { model | count = model.count + 1 } Decrement -> { model | count = model.count - 1 } view : Model -> Html Msg view model = div [] [ button [ onClick Increment ] [ text "+1" ] , div [] [ text <| String.fromInt model.count ] , button [ onClick Decrement ] [ text "-1" ] ] main : Program () Model Msg main = Browser.sandbox { init = initialModel , view = view , update = update } Model Message Update View
؆୯ͳElmͷ͡Ί͔ͨ ! EllieΛ͏ a. https://ellie-app.com/newΛ։͘ ! Elm ReactorΛ͏ a. npm
i -g elm, elm init͢Δ b. srcʹίʔυΛॻ͘ c. elm reactorͰىಈ ! ParcelΛ͏ a. https://parceljs.org/elm.htmlΛ։͘ b. parcelΛΠϯετʔϧ͢Δ c. ඞཁͳϑΝΠϧΛ࡞͢Δ d. ίʔυΛॻ͘ e. parcel index.htmlͰىಈ
ElmͱSPA ! ElmͷΞϓϦέʔγϣϯλΠϓ4ͭ͋Δ ◦ sandbox ▪ HTMLཁૉ͚ͩͷ࠷খߏɻ෭࡞༻֎෦ͱͷ௨৴Λѻ͑ͳ͍ ◦ element ▪
HTMLཁૉ͚͚ͩͩͲ෭࡞༻֎෦ͱͷ௨৴Λѻ͑Δ ◦ document ▪ elementʹՃ͑ͯHTMLͷϝλཁૉ(λΠτϧ)Λѻ͑Δ ◦ application ▪ documentʹՃ͑ͯHTMLͷϝλཁૉͱURLભҠΛѻ͑Δ -> SPA͕࡞ΕΔ ࢀߟ: https://package.elm-lang.org/packages/elm/browser/latest/Browser ը໘ͷҰ෦͚ͩElmͱ͍͏ಋೖՄೳ
Elmͷͭ·͖ͮͲ͜Ζ ؔܕతͳURLJSONσίʔυͷऔΓѻ͍ํΛ֮͑Δඞཁ͕͋Δ ࢀߟ: https://package.elm-lang.org/packages/elm/url/latest/Url-Parser
Elmͷͭ·͖ͮͲ͜Ζ ! ؾܰʹ෭࡞༻͕ىͤ͜ͳ͍ ◦ ྑ͘ѱ͘TEAʹकΒΕ͍ͯΔ ◦ ෭࡞༻Λى͍ͨ͜͠ͱ͖ɺ͓֎ͷjsͱձ͢Δͱ͖ඞͣCmdΛൃߦ͢Δඞཁ͕͋Δ
Elmͷྑ͍ͱ͜Ζ
ݴޠ༷͕γϯϓϧ ! ࠷খݶͷσʔλߏɺ੍ޚߏจɺࣜͷΈΛఏڙ ! ެࣜΨΠυΛݟͯ࣌ؒ͋ΕಡΈऴΘΔఔͷྔ ◦ https://guide.elm-lang.jp/
ඞཁͳػೳ͕͍͍ͩͨTEAʹ͋Δ ! TEAࣗମ͕Unidirectional Data FlowΛఏڙ͍ͯ͠Δଞɺඇಉظॲཧαϒε ΫϦϓγϣϯɺԾDOMɺϧʔςΟϯάɺϑϩϯτΤϯυ։ൃʹඞཁͳػ ೳ͕Ұ௨Γఏڙ͞Ε͍ͯΔɻͦͷͨΊϥΠϒϥϦϑϨʔϜϫʔΫͷબఆί ετ͕͍
࣮ߦ࣌҆શ ! ෭࡞༻Λͯ͢TEA͕ड͚ͭ͜ͱͰΞϓϦͷग़དྷࣄΛ΄ͱΜͲܕϨϕϧ ʹམͱ͢͜ͱ͕Ͱ͖ΔͨΊɺίϯύΠϧ͑͞௨Ε࣮ߦ࣌Τϥʔ͕΄ͱΜͲ ͳ͍
ϖʔδͷදࣔΞΫγϣϯܕ҆શ ! ϖʔδϝοηʔδͷܕΛఆٛ ͠ɺcaseͰذ͢Δ͜ͱʹΑΓ࿙ Εͳ҆͘શʹ࣮͢Δ͜ͱ͕Ͱ͖ Δ type Page = Blank
| LoginPage Login.Model | TodoPage Todo.Model | NotFoundPage NotFound.Model type Msg = LinkClicked Browser.UrlRequest | UrlChanged Url.Url | LoginMsg Login.Msg | TodoMsg Todo.Msg | NotFoundMsg NotFound.Msg
DOMґଘແ͠Ͱviewͷςετ͕Ͱ͖Δ ! viewHtmlΛग़ྗ͢Δ୯ͳΔؔ Ͱ͋ΔͨΊɺܕϨϕϧͷ੍Ծ DOMϨϕϧͰؔͷςετ͕Ͱ ͖Δ ! jest + enzymeͱ͔ΔΑΓ؆୯
ࢀߟ: https://package.elm-lang.org/packages/eeue56/elm-html-test/latest/
ίϛϡχςΟ͕׆ൃ ! ΠϕϯτDiscord͕׆ൃͰαϙʔτΛड͚͍͢ ◦ https://discordapp.com/invite/4j2MxCg ◦ https://elm-jp.connpass.com/
ElmͷͭΒ͍ͱ͜Ζ
Ϟδϡʔϧׂ͕ͭΒ͍ ! ػೳ͝ͱͷϞδϡʔϧׂͳͲͰϘΠϥʔϓϨʔτίʔυ͕૿͍͑͢ ◦ ԼҐϞδϡʔϧͰൃੜͨ͠MsgModelͷऔΓճ͠ ◦ جૅ͔ΒΘ͔ΔElmͷஶऀͷ@jinjor͞ΜͷϦϙδτϦʹ͋ΔReturnͰWrap͢ΔΓํ͕ྑ͞ ͦ͏ ▪ https://github.com/jinjor/elm-teapp/blob/master/src3/Return.elm
ܕΫϥε͕ͳ͍ ! ShowOrdΫϥεʹ͋ΔΑ͏ͳૢ࡞ඞཁʹԠͯࣗ͡લͰ࣮͢Δඞཁ͕͋ ΔͨΊɺ͜͜ͰϘΠϥʔϓϨʔτίʔυ͕૿͑Δ type FooBar = Foo | Bar
show : FooBar -> String show foobar = case foobar of Foo -> “Foo” Bar -> “Bar” deriving ShowΈ͍ͨͳ͜ͱͰ͖ͳ͍
HTML/CSSपΓͷબࢶ͕গͳ͍ ! elm-uiͱ͍͏elmઐ༻ͷϨΠΞτϥΠϒϥϦଘࡏ͢Δ͕ɺͲ͜·Ͱelm-ui ͰͬͯͲ͜·ͰcssͰΔ͔ͷઢҾ͖͕͍͠ ! elm-cssͱ͍͏CSS in JSͷElm൛Έ͍ͨͳͷ͋Δ͕jsonͱҧͬͯ͢ ͯؔͳͷͰײతʹ৮Δͷ͕͍͠ ◦
elm-mdlͱ͍͏Material DesignͷϥΠϒϥϦ͋ΔΒ͍͠... ◦ https://package.elm-lang.org/packages/debois/elm-mdl/latest/Material ! CSS ModuleͷΑ͏ͳ͍͍ײ͡ͷΈ͕ࠓͷͱ͜Ζͳ͍ ◦ ͍ۙͷ͋Δ͕ख͕͔͔ؒΔ
·ͱΊ ! TEAReduxͷݩωλʹͳͬͨ୯ҰํΞʔΩςΫνϟ ! Elm७ਮؔܕ͕ͩݴޠ༷ඇৗʹγϯϓϧ ◦ γϯϓϧ͞ͱͷτϨʔυΦϑͰɺ۪ʹϘΠϥʔϓϨʔτίʔυΛॻ͔ͳ͍ͱ͍͚ͳ͍͜ͱ ଟ͍ ◦ ݴޠ༷͕୯७ͰϘΠϥʔϓϨʔτ͕ଟ͍ͱ͍͏ͰGoʹ͍ۙҹ͋Δ
! TEAͷԸܙʹΑΓߴ͍࣮ߦ࣌҆શੑ͕͋Δ ڵຯ͕͋ΔਓੋඇElmͰ༡ΜͰΈ·͠ΐ͏ʂ