ScalaでUnion型

普段仕事ではTypeScriptを書いているので
const x: "kinoko" | "takenoko" = "kinoko";
みたいなの(Union型という)に見慣れていた。

趣味ではScalaを書いており、同じようなものを書きたくなった。具体的にはActiviryPubのActor Typesを表現するためにApplication, Group, Organization, Person, Serviceのどれかの値(いずれも文字列)をとるという型を作りたかった。

case class

しかし調べてみるとScalaにUnion型はない。自分でパッと思いついたのはcase classだ。ドワンゴのScalaテキストに近い用例が載っている。下にそれを引用する。

sealed abstract class DayOfWeek
case object Sunday extends DayOfWeek
case object Monday extends DayOfWeek
case object Tuesday extends DayOfWeek
case object Wednesday extends DayOfWeek
case object Thursday extends DayOfWeek
case object Friday extends DayOfWeek
case object Saturday extends DayOfWeek

sealed修飾子をスーパークラス/トレイトに付けることによって、その(直接の)サブクラス/トレイトは同じファイル内にしか定義できない

ので、パターンマッチするときにコンパイラがいい感じにチェックしてくれるというメリットがある。

上記を参考にこんな感じで実装してみた。欲しいのは文字列なので、toStringをoverrideしてクラス名をそのまま取得できるようにした。

objectにするとgetClass.getNameの末尾に$がついてしまうのでinitしている。最後の1文字を除去するというメソッドがある多機能さ、いかにもScalaっぽい。あるいはcase objectじゃなくてcase classにすればこんな小細工は不要だが、パラメータリストが必要になるという面倒臭さがある。どうあるべきなのか、自信ニキは教えてほしい。

Enum

もう一つ、これは同僚に教えてもらったものだが、Enum型を使う方法もある。

こちらは採用しなかったのであまり深入りしていない。もしかしたらこっちのほうが良かったかもしれない。いや、いま猛烈にそんな気がしている(表現したいのが単なる文字列なので)。

それにしても大事なのはググり力だ。僕が「Scala ユニオン型」で検索してもいい情報は得られなかったが、「代数的データ型」という言葉を知っていればこの記事に辿り着けただろう。思うに、体系的な勉強は裏切らないのだ。

型の道は深く険しい…

退職者と継承

記憶が正しければkwappaさんは僕が最初に会ったドワンゴのエンジニアだ。インターンの面接だったので2017年6月頃だったか。ベテランで年上で上司であることを忘れてしまうような話しやすい雰囲気の方で、それはそうである必要性を認識して努力されていたのだと思う。僕にとってのドワンゴのエンジニアの気質の体現者だ。

おそらく僕は認知されていないが、僕はkinoppydさんを認知している。なぜならSlackで存在感を放ちイベントを主催していたからだ。詳しくは言えないが社員同士がお互いの仕事を理解し仲良くなれる(?)ようなイベントを開いてくださった。それは入社して5ヶ月になる僕が持ち始めた問題意識と重なる。

kwappaさんやkinoppydさんが退職し技術コミュニケーション室がなくなっても、当たり前のように彼らの作った良い文化が継承され育っていくことが望ましいし、僕もその一助になりたい。

ダブルキーボードクライシス

突然キーボードの調子がおかしくなり、文字入力が出来なかったり、キーを1つ押すだけでアプリケーションが終了したりするようになった。しばらくは原因がわからず、Vivaldiのバージョンアップが悪かったのかと思ってChromeを起動してみたり、PCを再起動してみたりしていた。

次にキーボードが壊れたのかと思い、サブのキーボードならどうだろうと思って探したら、原因に気づいた。サブのキーボードが繋ぎっぱなしになっていて、その上に荷物が載っていた。常時ShiftかCtrlが押された状態になっていたのだろう。

くだらない話だ。

爆速帰宅無為ゲーム/ScalaのEvolutionsを捨てた

8/29

月末なので労働時間調整のために早く退勤した。時間が出来たのでDota2を3ゲームやったが全部負けた。自分一人の力ではどうしようもないと感じる負け方だったので辛い。

Scala+Play FrameWorkで作っているアプリケーションでDBの初期化のためにEvolutionsを使おうとしていたのだが

Unexpected exception[JdbcSQLSyntaxErrorException: Table "PLAY_EVOLUTIONS" not found;

というエラーがでてどうやっても解決できなかったので諦めた。情報がなさすぎる。

Evolutionsを使わなくても、適当なクラスのコンストラクタでcreate tableすれば済む話だった。ちゃんと公開するときはDBは別で作ればいいし。

睡眠時間の捻出

タイミングの妙で退勤が遅くなる日が続いてしまい、それでも毎日やりたいことはやるとすると睡眠時間にシワ寄せがくる。会社員になってから睡眠時間が短くても(5時間程度)でも日中は支障なく活動できるのだが、やはりダメージはあって集中力が落ちていたり軽い空腹でめまいが起きたりする。

ここ数日は冷やし中華を作っていた。麺を茹でてツナ缶・カット野菜を雑に乗せるだけでいい感じになる。

ああ、この先の人生、どんどん健康タグの出番が増えていくのだろう。

合間に頭を使う

8/27

仕事中にどうにも集中が続かなくて休憩エリアに行ったら気になる技術書があった。開いて読んでみたけどあまり頭に入らなかった。当然だ。

Ubuntu18.04の入力メソッド選択をMac風にした

Macは日本語入力と英語入力にそれぞれキーが割り振られており、そのキーを押せばその入力メソッドになることが保証される。一方でUbuntuはデフォルトだと一つのキーを押すことで切り替わる。これだと今どちらの入力メソッドが有効になっているかわからない。

入力メソッドの設定→全体の設定→Show Advanced Options

「入力メソッドをオンに」/「入力メソッドをオフに」にそれぞれ好きなキーを設定する。僕はMac風にスペースキーの左右のキーを当てた。使ってなかったし。

使ってない、使いみちのわからないキー、あるよね。

Dota2 TI9終幕

Dota2の世界大会TI9はOGの優勝で幕を閉じた。OGはTI史上初の2連覇だ。

第3ゲームのJeraxのRavage回避がえげつなかった。RavageはTideHunterのスキルで、広範囲の敵をスタンさせる。非常に強力なスキルで当て方次第でチームファイトの戦局を大きく変えることができる。

JeraxはRavageがギリギリ当たらない位置で待ち、Ravageを見てからカウンターを仕掛けている。以前もサポートは位置取りが大事と書いたが、これが世界最強のサポートプレイヤーの位置取りの上手さだ。震える。

買い物・映画・酒

8/24(土)

※この記事はビールを1瓶飲んで書かれた。

買い物

通勤にリュックを使っているのだが、これは高校入学時に買ってもらったもので、すでに小さな穴が空いていた。そろそろ新しいのを買おうと思い、銀座のそれっぽい店をウロウロしながら選んだ。

優れた製品であれば必然的に売れると思いがちだが、それは違う。ビジネス用のバッグという買い物をするのは初めてだし、おそらく今後の人生でも数回しかないだろう。万事がそうで、買い物、特に高い買い物というのは経験値が溜まりにくい。だから製品が良いものであるかをいろいろな方法で知る必要があるし、それを説得力を持って語れる人間を雇ってトークさせるというのはいい方法だ。

人間の販売員から情報を得るメリットは2つある。1つはそう簡単に嘘をつけないこと。会話で嘘をつくのは文字媒体で嘘を書くよりもはるかに難しい。もう1つは納得感。結局どれか一つしか買わないんだから実際のところ性能の小さな差なんて意味はない。むしろ熟慮して納得して買ったという記憶に意味がある。だからそういう気持ちになれるようなトークをしてくれる店員はありがたい。

映画

『二ノ国』を見た。前評判が酷かったので思ったよりは普通という印象になった。

サークルの先輩が酒を飲んでいたので映画のメンツで合流して飲酒した。話はもちろん楽しかったし、食べすぎず飲みすぎず酔いすぎず、いい塩梅で終われたのも良かった。

朝病院

8/23(金)

↑わからなくなるので書くことにした

木曜日に早く帰って寝たら頭痛は解消。出勤前に歯医者で抜歯の経過観察をしてもらい、問題ないというお墨付きを貰った。

今の僕の労働契約は11-15がコアタイムのフレックスなので、9時頃に予約しておけば仕事の前に病院に行けるのがいい。