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
Eff HandsOn
Search
machu
October 25, 2018
Technology
90
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Eff HandsOn
machu
October 25, 2018
More Decks by machu
See All by machu
NBAチームから学ぶ強いチームの作り方
machuz
0
74
Authorization to implement with Extensible Effect
machuz
0
470
アルプの 認証/認可分離戦略と手法
machuz
3
810
AuthzCtx - Alp社内共有会
machuz
0
100
アルプのEff独自エフェクト集 / Alp-original ’Eff’ pearls
machuz
1
2.3k
Scalebaseバックエンド構成について/the backend design of Scalebase
machuz
0
6.6k
SQL Meisterへの道 ~更新編~ / sql-meister-CUD
machuz
0
2.4k
SQL Meisterへの道 ~基礎〜参照編~ / sql-meister-R
machuz
0
2.8k
Authz
machuz
0
330
Other Decks in Technology
See All in Technology
Master Dataグループ紹介資料
sansan33
PRO
1
4.8k
本番に近いテストをもっと手軽に - Postmanで広がるAPIテストの世界 / Expanding the World of API Testing with Postman
yokawasa
1
130
サービス内で複数のOP・ASを連鎖させる(OAuth/OIDC Numa (Immersion) Workshop 2026)
oidfj
PRO
0
350
IHV like なユースケースへのOpenID Connect 関連仕様の適用事例
optim
0
350
「面白い!」を信じ抜け。激動の時代を貫く、オンリーワン・エンジニアの条件
kizawa2020
1
370
1000⼈規模のClaude Enterprise運⽤を「Oktaのグループ」と「Slack」に集約する
sansantech
PRO
0
490
AI時代の「OAuth認証」にどう物申すか?(OAuth/OIDC Numa (Immersion) Workshop 2026)
oidfj
PRO
0
340
わたしが知り合いゼロの勉強会に 行けるようになるまで
r5ni4
2
830
DMMブックスのNext.js化を加速させるAI活用 / Migrating DMM Books to Next.js with AI
kentarom
0
160
atproto spaces概要
yamarten
0
110
8bit CPU 2026
koba789
7
3k
GopherCon @シアトル に行ってきました
logica0419
0
330
Featured
See All Featured
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Evolving SEO for Evolving Search Engines
ryanjones
0
270
First, design no harm
axbom
PRO
2
1.3k
Believing is Seeing
oripsolob
1
200
Building a Scalable Design System with Sketch
lauravandoore
463
34k
Game over? The fight for quality and originality in the time of robots
wayneb77
1
260
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.2k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.3k
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
380
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
450
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.1k
Transcript
Eff hands on
༻ޠͷઆ໌ • Monad Transformer • Extensible effect (use FreeMonad) •
˒Freer effects (use FreerMonad, Efficient Freer) • جͷจͰ more Extensible effectͱݺΜͰ͍Δ
Ϟφτϥͱͷൺֱ(ࡶ)
߹ͷॱং • ϞφυτϥϯεϑΥʔϚʔ߹ͷॱংΛೖΕସ͑Δ͜ͱ ͕Ͱ͖ͳ͍ • EffOpenUnionʹΑͬͯՄೳ
࡞༻ͷॱং • ϞφυτϥϯεϑΥʔϚʔධՁॱΛೖΕସ͑Δͱ݁Ռ͕ มΘΔ • EffมΘΒͳ͍(Writer,Eitherɺܕʹ࡞༻͢Δͷ ී௨ʹॱংʹΑͬͯܕมΘΔ͕ܭࢉͷ݁ՌมΘΒͳ͍ • ʹαϯϓϧίʔυ͕͋Δ(Haskell͚ͩͲɾɾɾ) •
https://konn-san.com/prog/haskell/extensible-effects.html
ωετπϥΠͶΜ • EnglishͰ`Future[\/[E, A]]` ΛҾ͖ճ͢Α͏ʹ͠ɺͦΕҎ্ ͷෳࡶͳܕͳΔ͘Θͳ͍Α͏ʹͯ͠ճආ͍ͯ͠Δ͕ɺ 3ͭҎ্ͷϞφυΛ߹͢Δ߹liftͰ্࣋ͪ͛ͯॲཧ͢ Δඞཁ͕͋ΔɻৗʹίϯςΩετΛҙࣝ͠ͳ͍ͱ͍͚ͣɺ ਓྨͷΈͦʹͱͯΉ͔͍ͣ͠ •
EffͰશͯϑϥοτͳforࣜͰճͤΔɻωετ͠ͳ͍ɻ
ॏ͍ • Ϟφτϥɻܕ߹ΘͤͷͨΊʹ༨ܭͳ࡞ΒΕΔ • Future[\/[E,A]] • Future[\/[E,Future[\/[E, A]]]] • Future[\/[E,Future[\/[E,
Future[\/[E, A]]]]]] • (Θ͔Γ͘͢ಉ͡ܕʹͨ͠ͷͰਖ਼֬Ͱͳ͍͕)Έ͍ͨͳײ͡Ͱελο Ϋ͍ͯ͘͠ɻੵΊੵΉ΄Ͳॏ͍ • EffOpenUnion,EfficientFreerʹΑͬͯελοΫͷʹґଘ ͠ͳ͍ఆ࣌ؒͰͷॲཧ͕Մೳ
͍ํ
ͯ͢EffʹͳΔ • ͍··ͰM[+_]ίϯςΩετͷதͰ`.right`ͯ͠`toEitherT`͠ ͍ͯͨͷ͕ͯ͢EffʹͳΔ • Future,Either,DBIO,Reader,Writer,Taskɺͯ͢ͷMonadEff ม͢Δ͜ͱ͕Ͱ͖Δ • ࠓͷॴɺOptionͱTraversalܥ(List,Seq)Ҏ֎ΛEffʹ͢ΔΑ ͏ʹ͍ͯ͠Δ
͜ͷΜΛimport import org.atnos.eff.Eff import org.atnos.eff.syntax.all._ import org.atnos.eff.addon.scalaz.either._ import org.atnos.eff.addon.monix.task._ import
jp.eigosapuri.es.shared.lib.eff.either.EsErrorEffect._ import jp.eigosapuri.es.shared.adapter.secondary.eff._ import jp.eigosapuri.es.shared.adapter.secondary.eff.push.PushIOEffect._ import jp.eigosapuri.es.shared.adapter.secondary.eff.db.DBIOEffect._
͜Μͳײ͡ͰEffԽ override def resolveById[R: _dbio]( id: CallPreparationId )(implicit ec: ExecutionContext):
Eff[R, Option[CallPreparation]] = { for { resOpt <- fromDBIO(callPreparationStatusesDAO.ioFindById(id.value)) } yield resOpt.map(convertToDomainModel) } fromDBIOͰEffԽ͍ͯ͠Δ
؆୯ʹΈ͑Δ͔͕ͩ ͜ΕΊͬͪΌࣗ༝ߴ͍
for { x <- Option(7) y <- DBIO.successful(x) _ <-
-\/(UseCaseError) } y ཁҧ͏ܕͷ߹͕࣮ݱͰ͖͍ͯΔ for { x <- fromOption(Option(7)) y <- fromDBIO(DBIO.successful(x)) _ <- fromEsError(-\/(UseCaseError)) } y
ࠓޙɺFujiTaskΛՃ͍ͯ͘͠
ҙ
• ܕ߹Θͤήʔ͔Β։์͞Ε͍ͯ·͕͢ɺ·ͩཧͰ͖ͯ ͳͯ͘importήʔʹͳ͍ͬͯΔ • ࡞༻ͷλάͷཧ͕Ͱ͖͍ͯͳ͍
importήʔ • EffܥͷύοέʔδΛimport͠ͳ͍ͱ͍͚ͳ͍ • ScalazɺxxExtensionͱಉ͡ϊϦͰ͢ • ͏ͪΐ͍ཧͯ͠ҰՕॴimport͢Ε͕͍ͯͭͯ͘͢ΔΑ͏ʹ͠·͢ • ۩ମతʹҎԼͷύοέʔδ import
org.atnos.eff.Eff import org.atnos.eff.syntax.all._ import org.atnos.eff.addon.scalaz.either._ import org.atnos.eff.addon.monix.task._ import jp.eigosapuri.es.shared.lib.eff._ import jp.eigosapuri.es.shared.lib.eff.cache.CacheIOTypes._ import jp.eigosapuri.es.shared.lib.eff.push.PushIOTypes._ import jp.eigosapuri.es.shared.lib.eff.util.clock.joda.JodaTimeMEffect._ import jp.eigosapuri.es.shared.lib.eff.util.idGen.IdGenEffect._ import jp.eigosapuri.es.shared.lib.eff.either.EsErrorEffect._ import jp.eigosapuri.es.shared.adapter.secondary.eff._ import jp.eigosapuri.es.shared.adapter.secondary.eff.push.PushIOEffect._ import jp.eigosapuri.es.shared.adapter.secondary.eff.db.DBIOEffect._ import jp.eigosapuri.es.shared.adapter.secondary.eff.push.CacheIOInterpretationTypes._ import jp.eigosapuri.es.shared.adapter.secondary.eff.cache.interpreter.CacheIOInterpreter import jp.eigosapuri.es.shared.adapter.secondary.eff.db.interpreter.DBIOInterpreter import jp.eigosapuri.es.shared.adapter.secondary.eff.push.interpreter.PushIOInterpreter
࡞༻λάᶃ • EffͰͲͷ࡞༻ΛؚΉ͔Λࢦఆ͢Δඞཁ͕͋Δ • ྫ͑ɺDBIOͱIdGen,JodaTime,PushΛར༻͢Δ߹ type R = FxAppend[DBIOStack, FxAppend[ModelApplyStack,
PushIOStack]] • ͦΕͧΕͷத type DBIOStack = Fx.fx3[DBIO, Task, ErrorEither] type ModelApplyStack = Fx.fx2[IdGen, JodaTimeM] type PushIOStack = Fx.fx1[PushIO] • ͜ͷΑ͏ʹ͋Δఔͷ୯ҐͰ·ͱΊΒΕͨStackΛFxAppendͰ͕ͬͪΌΜ͜ Ͱ͖ΔɻޙͷΑ͏ʹUseCaseʹ࣮ͯ͠ߦ͢Δ͚ͩ startCallUseCase.execute[R](arg) • ಉ͡λάΛෳࢦఆ͢Δ͜ͱͰ͖ͳ͍
࡞༻λάᶄ • ࢦఆͨ͠λά(࡞༻)ΛҰͭҰͭධՁ͍ͯ͘͠ɻ • DBIOStack, ModelApplyStack, PushIOStackͷධՁҎԼͷΑ͏ʹͳΔ useCaseRes.runTransactionDBIO .runIdGen .runJodaTimeM
.runPushIO .runEsError .runAsync .runAsync .map(startCallPresenter.response) • ͜Ε `run` ͚ͩͰࡁΉΑ͏࣮ݧத
࡞༻λάᶅ • ͜ͷλάؔͷγάχνϟͱͯ͠Ҿ͖ճ͞ͳ͍ͱ͍͚ͳ ͍ def execute[R: _dbio: _task: _errorEither: _pushio:
_idgen: _jodaTimem]( arg: StartCallUseCaseArgs )(implicit ec: ExecutionContext): Eff[R, StartCallUseCaseResult]
͜ΕΒमਖ਼தͰ͢
˒YATTEIKI˒