Scala実践「Either型を使ってimmutable(不変)なコードを書こう!」
はじめに
みなさんこんにちは、プロダクト開発本部の亀梨です。
普段はXmediaOneというメディアプランニング・広告運用管理・トラッキング・マーケティング分析を行う
統合プラットフォームの開発を担当しています。
Scalaでイケてるコードを書きたい!
背景
わたくしはDACに入社してからScalaを書くことになりました。それまでは以前の会社で3年ほどPHPを書いてきて他のサーバーサイド言語は知らなかったので、
スクリプト言語からコンパイル言語への移行には最初は非常に苦労しました。…いや、今でも苦労しています(笑)。
さて今回はScalaのEither型を取り上げます。基本的な使い方と具体的な例を挙げて実践に活用出来るヒントになればと思います。
ちなみに過去にScala関連で書いた記事は以下となります。参考まで。
イケてるコードの定義
Scalaの特徴の一つとして「immutable(不変)」なコードが簡潔かつ副作用が無いと推奨されています。
そして今回のケースとしては、いかにimmutableにコードを書けるかがイケてるかどうかの定義とします。
このあたりはScalaビギナーが通る最初の関門ではないでしょうか。
Either型とは
それでははじめにEither型について触れておきましょう。
Either型はその名の通り「2つのうちどちらか一方」という値を表します。この特徴のため、主にエラー処理で「成功時の値or失敗時の値」として扱われることが多いです。EitherはRightとLeftという2つの値を持ちます。REPLでコードを書いてみましょう。
1 2 3 4 5 |
scala> val right: Either[String, Int] = Right(123) v1: Either[String,Int] = Right(123) scala> val left: Either[String, Int] = Left("abc") v2: Either[String,Int] = Left(abc) |
一般的にEitherを使う場合、Left値をエラー値、Right値を正常な値とみなすことが多いです。
英語の”right”が正しいという意味なので、それにかけているという説があります。
イケてるコード具体例
それではEither型の基本に触れた上で早速コードの具体例を書いていきます。
前提として、
- とある商品IDリストを格納している配列がある
- この商品ID一つ一つを元にDBにクエリを投げて、この商品が有効であるかを確認→有効であれば商品情報を取得する
- 商品情報を改めて配列に格納する
- 有効な商品に対してなんらかの処理を行う
という処理を行うこととします。
【びふぉー】mutable(可変)でイケてないコード
まずはEither型を使わない場合のコードです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import scala.collection.mutable.ListBuffer type itemId case class ItemFindForm(itemId: itemId) object ItemService { def find(itemFindForm: itemFindForm): List[item] = ??? } def itemIds: List[itemId] /** * Beforeここから */ val itemList = new ListBuffer[Message] itemIds.foreach(itemId => { val targetItem = ItemService.find(MessageFindForm(itemId)) if (targetItem.isEmpty) { // エラー処理 } else { itemList += targetItem.head } }) itemList...// 何らかの処理 |
はい、こんな感じです。このコードだと予め作成しておいた空の配列に有効な商品情報を次々と追加していく形になるので、
itemListがmutable(可変)となり副作用を伴います。。。
まぁこの書き方でも悪くはないと思うのですが、せっかくScalaで書くならその特徴を生かしたいですよね。
【あふたー】immutable(不変)でイケてるコード
では次にEither型を使ってリファクタリングしたコードです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import scala.collection.mutable.ListBuffer type itemId case class ItemFindForm(itemId: itemId) object ItemService { def find(itemFindForm: itemFindForm): List[item] = ??? } def itemIds: List[itemId] /** * Afterここから */ val result: Seq[Either[String, Message]] = itemIds.map(itemId => { val targetItem = ItemService.find(ItemFindForm(itemId)) targetItem.headOption.toRight(s"$itemId not found.") }) val itemList: Seq[Item] = result.collect { case Right(item) => item } if (itemIds.length != itemList.length) { // エラー処理 } else { // 何らかの処理 } |
はい、これでEither型で関数型を使ったコードとなります。
有効な商品情報と無効な商品を一度に配列に格納でき後から追加ができないようになるため、
immutable(不変)で副作用のないコードとなります。あと最後のif文でエラー処理か正常の処理かを分岐しているため可読性も増しているかと思います。
あと個人的にimmutableなコードが書けたときになんとも言えない高揚感と興奮を覚えます(笑)。
まとめ
というわけで簡単ではありますがEither型の具体例を紹介いたしました。
わたくしもまだまだScalaは勉強中でビギナー感が抜けない状態ではありますが、だからこそ気づきも多いかと思うので
またなにか良い具体例があればここで共有できればと思います。
それではまた!

関連記事
-
-
AWSにRailsアプリをデプロイする(公開編)
次にデプロイするため“aws rails デプロイ”でググってみるとunicorn、nginxというキーワードがでてくるので とりあえずこれを設定していきます。 アプリのsecret_key_baseの設定 [crayon-6004bedd87d0b455513 …
-
-
【未経験からのRuby on Rails – 第1回】楽しく書けるプログラミング言語 “Ruby” とは
こんにちは、はじめまして。新卒1年目のmatsuari(女子)です。 この度、Rubyの勉強を始めることになりまして、 まずはたくさんあるプログラミング言語の中で、なぜ自分がRubyを学ぶのか? しっかりと把握した上で学習に取り組んでいきたいと考え、『Rubyとは何か?』調べました。 超基礎的なこと …
-
-
iOS端末情報をTreasureDataに送るアプリをswiftで作ってみた。
はじめまして、2年目のOyamanです。 通常業務とは別のことになりますが、Swiftに触れる機会が少しあったので、スマホ関連の記事を書かせていただきます。 はじめに SwiftとTreasureDataのSDKを使って、 iOSの端末情報をTreasureDataへ送るアプリを作ってみます。 今回 …
-
-
【小ネタ】Javascriptのconsoleオブジェクトをもっと便利に使う方法
すごく便利なconsoleオブジェクトですが、ブラウザによってサポートされているメソッドが なかったり、そもそもconsoleオブジェクトが使えなかったりと、たまに不便だったりします。 そんなときによく使う便利なコード。 [code language=”javascript” …
-
-
ECMAScript6を使ってみた ~「Promise」編
ECMAScript6とは 一応ちょっとだけ説明しておくと、 ECMAScript(エクマスクリプト)は、Ecma Internationalによって標準化されたスクリプト言語で、バージョン6が2015 年 6 月 17 日に標準仕様として発行されました。(以下、ES6と呼びます) ES6ではcon …
-
-
Scala番外編「Boxに保存したファイルをBox APIを使ってダウンロードしよう!」
はじめに みなさんこんにちは、プロダクト開発本部の亀梨です。 普段はXmediaOneというメディアプランニング・広告運用管理・トラッキング・マーケティング分析を行う 統合プラットフォームの開発を担当しています。 Box APIを使う背景・目的 DACはメディアレップです メディアレップとは、インタ …
-
-
Polymer core-ajax の使い方
Polymerのcore-ajaxの使い方。 まずは、index.html [code language=”html” title=”index.html”] <!doctype html> <html> <head> …
-
-
プログラミング初心者がswiftでゲームアプリ的なものを作ってみた。
こんにちは、DAC2年目のkumataです。 普段は素敵な先輩方に囲まれてインフラ周りのお仕事をさせて頂いていますが、 今回は業務とは全く関係ないプログラミングをやってみました。 全く初心者なのですが、swift+Xcodeで簡単にスマホゲーム的なものが作れました。 初心者の目線から作成方法をつらつ …
-
-
SDKってどうやって作ってるの?【Android編】
こんにちは。4度目の投稿です。 現在私はAndroidのSDKを開発しています。 javaにもAndroidにもSDKにも手を出したのは初めてなので、最初はそもそもSDKのイメージが湧かず、ふわふわした状態で始めました。 SDKと調べても「あるソフトウェアを開発するために必要なプログラムや文書などを …
-
-
PyStanによるはじめてのマルコフ連鎖モンテカルロ法
はじめに こんにちは。システム開発部の中村です。 社内で行っている『データ解析のための統計モデリング入門』(所謂緑本)の輪読会に参加した所、 大変わかりやすい本だったものの、Macユーザには悲しい事に実装サンプルがWinBUGSだったため、 9章の一般化線形モデルのベイズ推定によるアプローチをPyt …