Scala.jsとcatsとその仲間たち

## これは何?

この記事は、[FOLIO Advent calendar 2019](https://qiita.com/advent-calendar/2019/folio-sec) の15日目の記事です。
14日目は、[yasuharu519](https://qiita.com/yasuharu519)さんの[2019年発表された Datadog のプロダクトを勝手に紹介していく](https://yasuharu519.hatenablog.com/entry/2019/12/14/002155)でした。
16日目は、[ihcomega](https://qiita.com/ihcomega)さんの[1on1は必ず議事録を残す(ときどき公開だってする)](https://ihcomega.hatenadiary.com/entry/2019/12/16/233302)です。

併せて、[Scala Advent Calendar 2019](https://qiita.com/advent-calendar/2019/scala) の15日目の記事です。
14日目は、[showmant](https://qiita.com/showmant)さんの[Akka HTTPでメンテナンス時のレスポンスを制御する](https://qiita.com/showmant/items/0f543dde9414d92dfc3c)でした。
16日目は、[poad1010](https://qiita.com/poad1010)さんの[Scala で AWS CDK Javaを使ってみる](http://poad1010.hatenablog.com/entry/advent/2019/scala)です。

普段は、証券基盤チームの一員としてScalaを利用した基盤の開発をしています。
7月に参加してから約半年、新しい業務のドメインを学びつつ、より良いものを提供しようと日々開発に勤しんでます。

今回は、1.0.0-RC2がリリースされ、2020年の1月に正式リリースの兆しが見えてきた[Scala.js](https://www.scala-js.org/)と、社内でも使われている [typelevel/cats](https://typelevel.org/cats/) が実はScala.jsでも利用できることについて紹介します。

## Scala.jsについて

私が[Scala関西 Summit 2019](https://2019.scala-kansai.org/)にて「[Scala.jsでGoogle Cloud Functionsを利用する前に知りたかったこと](https://2019.scala-kansai.org/sessions.html#よしだ)」というタイトルで発表した[資料](https://docs.google.com/presentation/d/e/2PACX-1vTLDYcTXtDT6fq4alqsWElsWN5_oP5yT9kcA7rCp7Z3z9uMsJZWY14WeqpDCl4wygu4a5mkD0eQFdO_/pub?start=false&loop=false&delayms=3000&slide=id.p)からいくつか抜粋しますが、以下の内容のプロダクトです。

- 普段利用しているScalaのコードが、ほぼJavaScriptへ変換出来る
- JavaScriptよりも強力に型の恩恵を受けられる
- Facadeを利用することで、npmのライブラリも導入することが出来る

いくつかsbtのプラグインをプロジェクトへ導入することで始められるのも、Scala.jsの良さだと思います。
決して万人にお勧めできるプロダクトではないですが、プロジェクトの内容によってはとても心強いプロダクトなので、試してみてはいかがでしょうか。

## Scala.jsとcatsについて

catsは、typelevelの中で代表的なライブラリで、関数型プログラミングをしたい時に必要なデータ型等を提供してくれます。
実は、プロジェクトの[plugins.sbt](https://github.com/typelevel/cats/blob/master/project/plugins.sbt#L13)を見てみるとscala.jsのpluginが見えると思います。
Scala.jsのプロジェクトへの導入も簡単で、以下のように依存関係を記載することで利用できるようになります。

```scala
    libraryDependencies ++= Seq(
      "org.typelevel" %%% "cats-core" % "2.0.0"
    )
```

## catsとその仲間たち

以下に挙げるライブラリは、catsのエコシステムの中でもScala.jsに対応している数少ないライブラリの一例です。
まだ、自分が触っていないのを挙げるのは個人的によろしくないと思うので、ここに挙げた以外のも興味がありましたら、[https://typelevel.org/cats/](https://typelevel.org/cats/)から探してみてはいかがでしょうか。

### cats-effect
https://typelevel.org/cats-effect/

catsのエコシステムの中で特にIOモナドを扱っているのが、この cats effectです。
他のcatsのエコシステムのベースとなる事が多く、JavaScriptのpromiseよりも柔軟に非同期処理を扱う事が出来ます。

### cats-retry

https://cb372.github.io/cats-retry/

リトライ処理を組み込む際に自分で書くのは骨が折れます。その際に助けとなるのが、このcats-retryです。
リトライのPolicyを細かく設定することが出来ます。Scala.jsでも利用できるので、外部APIとの連携等でFaaSのリトライだけに頼る事なく実行できるので、呼び出し回数が多い場合は助かります。

### circe

https://circe.github.io/circe/

Scala.js でもJavaScriptのJSONを扱うことは出来ますが、parseしながらある一部の値を使いたい等の操作ができるので、とても重宝します。
もちろんcase classのdecode/encodeで使われることが多いので、JSONの緩い世界から強い型の世界の橋渡し役として活躍します。

### refined

https://github.com/fthomas/refined

Scalaでもある程度強い型を定義することは出来ますが、よりDomesticな型を表現したい場合に使います。
ライブラリが標準で数字や文字列に関する定義を提供している為、組み合わせることで単なる文字列や数字以上の制約を型として表現できるようになります。circeとの組み合わせも出来るのでJSONをより安全に扱うことが出来るようになります

### Monocle

http://julien-truffaut.github.io/Monocle/

単体で使うというよりもcirceと組み合わせて使うことが多いです。
特に、JSONのある項目の値を変えて扱いたいといった場合に、型の恩恵を受けたまま操作することが出来るようになります。

### hammock

http://pepegar.com/hammock/

catsのエコシステムでもhttp clientはいくつかありますが、その中でもScala.jsで使えるのは限られています。その一つがこのhammockです。
特にcirceと組み合わせることで外部APIとの連携が型に守られたまま扱うことが出来ます。

### fs2

https://fs2.io/

Stream処理をしたい場合、catsのエコシステムでは、fs2を利用します。
cats effectのIOをベースにfan-in, fan-outといったStream処理特有の処理を書くことが出来ます。

### Monix

https://monix.io/

fs2がStream処理で使うことが多いなら、Monixは非同期処理に使うことが多いです。
cats effectのIOベースになった上に、cats effectで非同期処理を扱うよりも簡単に、効率よく扱うことが出来ます。
特にリアクティブプログラミングに向いているため、フロントエンドでも使えるのではないかと思います。

## まとめ

いかがだったでしょうか。
catsのエコシステムの広がりは、以前に比べると目を瞠るものがあります。
フロントエンドのJavaScriptもScalaのように型の恩恵を受けたまま扱いたいと思うことはあるのではないでしょうか。
その際には、Scala.jsという選択肢を考えてみるのもおもしろいかもしれません。