【Scala】Eitherについて、個人的なまとめ【チラシの裏】

今日、会社の先輩にScalaのEitherについて聞かれた。
今のチームで一番Scalaに触れているのは多分僕だし、Repositoryの返却値をTryなどにくるむのはどうだろうと提案した事が発端になる。

けれども僕はTry(役目としてはEither)のメリットを上げきれなかった。
正直悔しいので、個人的にまとめてみる
チラシのウラっていうのは、自分の考えをまとめるために書きだしたからなので、ひどい乱文だったりする。

【条件】
製品はWebアプリであり、mysqlとredisと連携する。
playframeworkを使用している

【Eitherのメリット】
エラーが起こることを型で表現できる
エラーという副作用を型で表現することで次の受け取り手が適切な処理をかける
参照透過性は、遅延評価が原則ではないScalaでは、設計的な意味合い以外での効能は薄い(?)


【デメリット】というか先輩から突っ込まれて答えられなかった事
メモリ領域を食い尽くすような例外を考えたらすべてEitherでくるまないとダメではないか
すべてくるまないのであれば、どのレベルの例外からくるむべきかの閾値は?
適切な処理の箇所がレイヤ的に上部にあった場合、ひたすらTryで返すことになるのでは ->冗長では



直近思いつく最大のメリットは、やはりそのメソッドの処理の結果として例外なりのエラーが起こるという文脈を型で表現できる事だと思う。
Optionが処理の結果、nullが入る可能性がある事を表現するように、エラーを表現して渡すことで対エラー処理を忘れることなく実行できる
とはいえ、アーキテクチャとして、そのエラーを解釈して処理を分ける部分がかなり上位のコントローラ層にあり、そこでエラーをキャッチしてユーザにエラーレスポンスを返すという仕組みを用意していた場合、いちいちTryでくるんで返すのは無駄では、というのもある。
ただし、その場合、処理の結果として例外が発生する事を型で表現できず、その文脈が欠落する。

チームプロジェクトの場合、前提条件などの制約が入る。自由にしてしまうと、予想外の例外や責務がわかりづらくなり、プロジェクトが拡大するにつれてバグが生まれやすい環境になって、生産性も再生産性も落ちる
だからそこに制約が入る
型とは制約だ。それを言語レベルで担保することにより目に見えない副作用を制限する役割を担保する。
それとは別に、コーディング規約や設計上の制約、つまりはコード外での制約もある。

コードの外で制約を表現すると、プロジェクトのコンテクストが一段階複雑になり、プロジェクトでの経験値が必要になる。
要するに、EitherなどのMonadの最大の恩恵は、型がその経験を担保する事により、コードの世界だけでプロジェクトの設計を把握できるようになることなのではないだろうか。
そのかわり、いちいちMonadでラッピングするため、それを解決する手間がかかる。のかもしれない


でも、Eitherでくるめべき例外の閾値みたいなのは、正直わからないな……外部と接続するところが副作用だからくるむべきというのはなんとなくわかるんだけれど、すごい感覚的な気がする。