Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up
for free
Eff HandsOn
ma2k8
October 25, 2018
Technology
0
29
Eff HandsOn
ma2k8
October 25, 2018
Tweet
Share
More Decks by ma2k8
See All by ma2k8
ma2k8
0
12
ma2k8
0
11
ma2k8
0
170
ma2k8
0
2.6k
ma2k8
3
5.9k
ma2k8
1
26
ma2k8
1
1.4k
ma2k8
1
1.5k
Other Decks in Technology
See All in Technology
yshr1200
0
170
miyakemito
1
610
pohjus
0
3.3k
uzabasetech
1
590
kanaugust
PRO
0
110
gamella
3
1.5k
udonyuya
1
550
tenjuu99
1
280
leaner_tech
0
770
torisoup
11
6.1k
khrd
1
640
legalforce
PRO
4
280
Featured
See All Featured
stephaniewalter
260
11k
smashingmag
230
18k
hatefulcrawdad
257
17k
tmm1
61
9.4k
revolveconf
200
9.7k
jacobian
255
20k
thoeni
3
610
jponch
103
5.1k
jcasabona
8
550
orderedlist
PRO
328
36k
chriscoyier
779
240k
skipperchong
8
720
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˒