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

Scala ZIOをバッチ処理に使ってみた

Scala ZIOをバッチ処理に使ってみた

More Decks by リチャード 伊真岡

Other Decks in Technology

Transcript

  1. Scala ZIOをバッチ処理で使ってみた

    リチャード 伊真岡

    マーベリック株式会社


    View Slide

  2. 関数型の最大のメリット(の一つ)はtestability! ①

    “Functional programming ordinarily
    gives us the incredible ability to
    easily test our software.”
    Beautiful, Simple, Testable Functional Effects for Scala
    JOHN A DE GOES (blog) Feb, 2019
    John De Goes氏 ZIO作者

    View Slide

  3. 関数型の最大のメリット(の一つ)はtestability! ②

    “I would argue that the whole point of
    functional programming in general is
    testing”
    Free as in Monads - ETE 2017
    Daniel Spiewak氏

    View Slide

  4. 純粋関数はtestabilityが高い

    input 1
    input 2
    output

    View Slide

  5. 純粋関数はtestabilityが高い

    test input 1
    test input 2
    output
    expected
    output
    assert!

    View Slide

  6. 副作用はテストが難しい

    Database
 File
 HTTP


    View Slide

  7. 副作用を含むコード

    副作用

    純粋関数呼び出し


    View Slide

  8. テストしづらい...

    そこで関数型のテクニックを使う!


    View Slide

  9. descriptionとinterpreterの分離

    val programDescription = for {
    … … … } yield finalResult
    def main(args: Array[String]): Unit = {
    interpreter.unsafeRun(programDescription)
    }

    View Slide

  10. descriptionとinterpreterの分離

    val programDescription = for {
    … … … } yield finalResult
    def main(args: Array[String]): Unit = {
    interpreter.unsafeRun(programDescription)
    }

    View Slide

  11. descriptionとinterpreterの分離

    val programDescription = for {
    … … … } yield finalResult
    def main(args: Array[String]): Unit = {
    interpreter.unsafeRun(programDescription)
    }
    tree構造

    副作用


    View Slide

  12. descriptionとinterpreterの分離

    ● この流れに沿うテクニックとしてfree-monad, tagless-finalなどがある
    ● しかし...

    View Slide

  13. John De Goes氏のThe Death of Tagless Finalより

    https://skillsmatter.com/skillscasts/13247-scala-matters

    View Slide

  14. John De Goes氏のThe Death of Tagless Finalより

    https://skillsmatter.com/skillscasts/13247-scala-matters

    View Slide

  15. 副作用同士はtestで比較できない

    input 1
    input 2
    description
    expected
    description
    assert!???
    e.g. println

    View Slide

  16. JOHN A DE GOES - The False Hope of Managing Effects with Tagless-Final in Scala 


    View Slide

  17. Scala ZIOの方がtagless finalよりイイ?

    ● testabilityの向上
    ● とくに非関数型プログラマになじみやすい(らしい)
    ○ -> ZIO自体の開発動機のひとつ
    (ZIO作者談)


    View Slide

  18. Scala ZIOをバッチ処理で使ってみた


    View Slide

  19. ZIOの戻り値型

    ZIO[R, E, A]
    ● R - Environment Type.
    ● E - Failure Type.
    ● A - Success Type.

    View Slide

  20. ZIOの戻り値型

    ZIO[R, E, A]
    ● R - Environment Type.
    ● E - Failure Type.
    ● A - Success Type.

    View Slide

  21. ZIOの戻り値型

    ZIO[R, E, A]
    ● R - Environment Type.
    ● E - Failure Type.
    ● A - Success Type.
    DB,
    Config,
    ThreadPool

    View Slide

  22. View Slide

  23. これがCirquaだ!


    View Slide

  24. これがCirquaだ!


    View Slide

  25. これがCirquaだ!


    View Slide

  26. これがCirquaだ!


    View Slide

  27. これがCirquaだ!

    独立している!!

    View Slide

  28. ZIOの戻り値型

    ZIO[R, E, A]
    ● R - Environment Type.
    ● E - Failure Type.
    ● A - Success Type.
    DB,
    Config,
    ThreadPool

    View Slide

  29. ZIOでのDI手順例: DIするコンポーネントを特定

    Config S3
    Logger
    Athena
    Database etc

    View Slide

  30. trait S3Service {
    def getFromS3(...): ZIO[Any, Throwable, S3Result]
    }
    S3
    例:
 cake pattern


    View Slide

  31. trait S3Service {
    def getFromS3(...): ZIO[Any, Throwable, S3Result]
    }
    S3
    trait S3Component {
    val service: S3Service
    }

    View Slide

  32. trait S3Service {
    def getFromS3(...): ZIO[Any, Throwable, S3Result]
    }
    S3
    trait S3Component {
    val service: S3Service
    }
    object S3ProductionComponent
    extends S3Component {
    val service: S3.Service = ...
    }

    View Slide

  33. trait S3Service {
    def getFromS3(...): ZIO[Any, Throwable, S3Result]
    }
    S3
    trait S3Component {
    val service: S3Service
    }
    object S3ProductionComponent
    extends S3Component {
    val service: S3.Service = ...
    }
    object S3TestComponent
    extends S3Component {
    val service: S3.Service = ...
    }

    View Slide

  34. trait MainComponent extends
    S3Component with
    AthenaComponent with
    DatabaseComponent with
    ConfigComponent with
    LoggerComponent with


    cake pattern


    どっちかというとおまんじゅうに見える 


    View Slide

  35. \アッタカイヨー/


    View Slide

  36. CirquaでのZIO利用例

    def run(args: List[String]) = {
    _ _ _ result ...
    } yield ()

    View Slide

  37. CirquaでのZIO利用例

    def run(args: List[String]):
    ZIO[S3Component with AthenaComponent with …, Throwable, BatchResult] = {
    _ _ _ _ ...
    } yield ()
    あえてZIOの型を書いてみる(必要ない場合普通は書かない)


    View Slide

  38. CirquaでのZIO利用例

    def run(args: List[String]):
    ZIO[S3Component with AthenaComponent with …, Throwable, BatchResult] = {
    _ _ _ _ ...
    } yield ()
    def setUp(...): ZIO[..., …, ...] = for {
    _ …
    }

    View Slide

  39. cakeってアンチパターンじゃないの?


    View Slide

  40. 分割された一つ一つのfor文は

    小さいcakeになるので、昔ながらの
    cake patternの問題を避けられる

    ZIO cake (module pattern)

    (らしいよ)

    View Slide

  41. ZIOとテスト
    ● Effect(副作用)はだいたいDIのコンポーネントに集中する
    ● DIを使ってテスト!...あれ?

    View Slide

  42. 関数型の最大のメリット(の一つ)はtestability! ②

    “I would argue that the whole point of
    functional programming in general is
    testing”
    Free as in Monads - ETE 2017
    Daniel Spiewak氏 関数型プログラミング等で特に著名
    これ、Algebraic Lawsの話をしている。 (リチャード)

    View Slide

  43. Algebraic Lawsの話
    ● プログラムが満たすべきルールを、型クラスが満たすべきルールとして定義してい
    る(はず…間違ってる?)

    ● そもそもデータベース副作用、ファイル副作用に満たすべきAlgebraic Lawつまり代
    数的規則などない、数学的に厳密に規則を議論できない

    ● それはtagless finalに代えてZIOを導入しても同じ


    View Slide

  44. John De Goes氏の別の発言

    “Tagless-final type classes do not, in general,
    have algebraic laws. Most have no laws at all.
    This represents a serious abuse of the construct
    of a type class ...”
    Beautiful, Simple, Testable Functional Effects for Scala
    JOHN A DE GOES (blog) Feb, 2019
    John De Goes氏 ZIO作者

    View Slide

  45. ZIOとテスト
    ● イマイチdescriptionとinterpreterの分離によるtestabilityの向上がわからない
    ● DIを上手く使えばテストが書けるが、それはdescriptionとinterpreterの分離による
    testability向上ではないのでは?
    ● 結局この点はについてはtagless-finalも同じだったし、ZIOでも副作用のtestability
    が向上してるわけではなさそうに見えるのだが…
    ● というわけでdescriptionとinterpreterの分離の流れに沿うZIOもtestabilityの向上と
    いう面で見るとメリットが「私には」理解できなかった
    ● モックを上手く使えばテストが書けるが(同上)

    View Slide

  46. ZIOは理解しやすくtestability以外の

    メリットも有る、という話なら分かる


    View Slide

  47. ZIOの他のメリット!!


    View Slide

  48. 省略

    ごめん、まとめる時間がなかった

    View Slide