2024.12.19
システムの穴を運用でカバーしようとしてミス多発… バグが大量発生、決算が合わない状態から業務効率化を実現するまで
リンクをコピー
記事をブックマーク
中村学氏(以下、中村):ScalaではHaskell等から輸入された型クラスが使われています。専用の構文が用意されているわけではなく、implicit parameterという言語機構を使って実現しています。
これはちょっと語弊ありますね。implicit parameterそのものが型クラスを実現するために作られた言語機構でもあるので、専用の言語機構があるという言い方も、できると言えばできますが、型クラス以外にもimplicit parameterは使えるので、そういう表現をしています。
そもそもimplicit parameterって何なのよという話ですが、メソッドの引数グループのところにimplicitという修飾子を付けると、そのメソッドを呼び出すところで、スコープ中に型が一致するimplicitな値が存在していれば、呼び出しのときに明示的に書かなくてもコンパイラが補ってくれる仕組みです。
逆に、スコープ中に型が一致する値が存在しなかったり、複数あってどれを選んでいいかわからないときには、コンパイルエラーになります。ではそのimplicitな値とは何なのか。これも単純で、定義時にimplicitという修飾子を付けた値です。val foo: Fooなどで定義したときにimplicitと付けられるられますし、Singletonオブジェクトを宣言するときも、implicitは付けられます。
逆に、値だけじゃなくてdef、メソッド定義でもimplicitは付けられます。これは、その評価結果がimplicitな値になるという感じです。
じゃあ、そもそも型クラスは何に使うの? というと、合成可能性のある制約を型に提供できますよ、と。ちょっと意味がわからないですね。
型への制約というと、通常のtraitのmixinのようなものでも表現できます。Javaでもよくありますが、Comparableのようなものです。値を比較することができる制約を表したいときに、traitを使います。クラスを定義するときにそのtraitをmixinすることで、そのクラスは比較可能なんだよ、と表せる感じです。型への制約という意味だと、通常のtraitのmixinでも表せます。
通常のtraitのmixinだと、そのジェネリックなクラスに対して十分な制約をかけられません。例えば、さっきのようなIntを持っているFooというクラスだったら、Foo同士を比較したいときにはそのIntの値を比較してあげればよいですが、逆にジェネリックなBarというクラスの定義をしたいと。
ただこれを比較可能にしたいとなったときに、Aが比較可能じゃないと、そもそも比較ができなくなってしまいます。どうしたものか。そもそも型引数A自体にComparableの制約を設けてしまえばいいんじゃないか。これも1つ成り立ちますよね。しかし、そのBarが比較可能な型のみしか使えないクラスになってしまって、これはこれで不便になってしまいます。
それを解決するために、型クラスが使われます。制約自体をクラスの定義と分離して書けるようにする感じです。ComparableではなくComparator[A]というのを用意して、compareメソッドとしては、値を2つ取って比較するtraitを用意しますと。
クラス自体は普通に何もmixinせずに定義します。implicitな値として、Comparator[Foo]のようなもの用意してあげる。Foo同士を受け取って比較するような定義ができます。Comparableのパターンと、Comparatorを使うパターンが同じような感じで書けます。
上がComparableを使ったときのパターン。それをFooに直接mixinしているケースです。下がComparatorを使っていて、implicitな値としてComparatorを用意している感じになります。おもしろいのは、ある型引数が特定の型クラスインスタンスを持っているときに限って、型クラスインスタンスを提供するような定義が可能です。
さっき言っていたような、クラスBarが型引数Aを持っているようなときに、implicit valueとしてComparator[Bar]を用意したいとなります。最初にimplicit valueを定義するときにvalとかobject以外にもdefで定義できることを最初に伝えたと思いますが、そのときの定義に、さらにimplicit parameterを自分自身で受け取ることもできます。
そのため、BarのComparatorを定義するときにimplicit parameterとしてAのComparatorを受け取るような書き方をすると、Aが比較可能なときだけ、Barが比較可能になるようなComparatorを定義できる。使う側としては、mixinと変わらない使い方ができます。
sortメソッドでは、AがComparableなときに、Traversable[A]とmixinで型の制約を表現できますが、同じようにimplicit parameterでsort[A]を表現するときTraversable[A]を受け取ってimplicit parameterとしてComparatorを受け取るようなかたちで定義しておくと、実際に使うときは同じようにsortにfoosを渡してあげればいいだけになります。
使う側としてはmixinでも型クラスでもそんなに変わりませんが、その「比較可能な」というのが、Aが再帰的に比較可能かどうかというのを見てチェックできる感じです。
まとめると、Scalaだと型の制約を表現するときに、型クラスを使えます。型クラスはそのimplicit parameterを使って実現でき、型クラスを使うと、より柔軟な制約を表現できます。
さっきみたいにジェネリックな型だと単純にComparableのようなものをmixinできませんが、Comparatorのような型クラスにしてあげることで、より再帰的に制約を表現できます。いわゆる「型クラス」とよく言われますが、ある種のデザインパターンの1つだと思ってもらえればいいかなという感じです。
よくあるのが、JavaだとSerializableというインタフェースがあって、オブジェクトの状態をバイト配列に書き出して、バイト配列からまたオブジェクトに戻すような仕組みがあります。Javaのリストだと中身がSerializableでないとシリアライズにリストが失敗してしまうような状況がありますが、そこを普通のインタフェースで表現しているので、中身がシリアライズかどうかをコンパイラがチェックできません。
実際に、実行時に直列化が失敗するようなことがよくありますが、Scalaの場合はこの型クラスを使って表現することで、あくまで中でもっている型が直列化可能であれば、そのリスト全体も直列化可能な指定ができるので、その辺はだいぶ安全に実現ができる仕組みになっています。という感じで、型クラスの説明です。
残りで宣伝をさせてください。Tech to Valueという会社では、Scalaのオンラインコードレビューサービスを提供しています。SlackやGitHubなどでプルリクベースでレビューようなものを、サービスとして提供しています。「Scalaでプロジェクトをやりたいけどエキスパートがいなくてちょっと不安」というチームなどにフィットする感じです。
僕のリソースの問題で受付を停めていましたが、いろいろな世界的な状況の変化でプロジェクトが終了したり、状況が変わってきていくらか受け入れる状況があるので、もしよかったら申し込んでもらえたらと思います。
またもう1つ。エフ・コードという会社ではエンジニアを募集しているので、こちらもよかったら、興味のある方は見ていってください。
という感じで以上です。ご清聴ありがとうございました。
2024.12.20
日本の約10倍がん患者が殺到し、病院はキャパオーバー ジャパンハートが描く医療の未来と、カンボジアに新病院を作る理由
2024.12.19
12万通りの「資格の組み合わせ」の中で厳選された60の項目 532の資格を持つ林雄次氏の新刊『資格のかけ算』の見所
2024.12.16
32歳で成績最下位から1年でトップ営業になれた理由 売るテクニックよりも大事な「あり方」
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
PR | 2024.12.20
モンスター化したExcelが、ある日突然崩壊 昭和のガス工事会社を生まれ変わらせた、起死回生のノーコード活用術
2024.12.12
会議で発言しやすくなる「心理的安全性」を高めるには ファシリテーションがうまい人の3つの条件
2024.12.18
「社長以外みんな儲かる給与設計」にした理由 経営者たちが語る、優秀な人材集め・会社を発展させるためのヒント
2024.12.17
面接で「後輩を指導できなさそう」と思われる人の伝え方 歳を重ねるほど重視される経験の「ノウハウ化」
2024.12.13
ファシリテーターは「しゃべらないほうがいい」理由 入山章栄氏が語る、心理的安全性の高い場を作るポイント
2024.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
Climbers Startup JAPAN EXPO 2024 - 秋 -
2024.11.20 - 2024.11.21
『主体的なキャリア形成』を考える~資格のかけ算について〜
2024.12.07 - 2024.12.07
Startup CTO of the year 2024
2024.11.19 - 2024.11.19
社員の力を引き出す経営戦略〜ひとり一人が自ら成長する組織づくり〜
2024.11.20 - 2024.11.20
「確率思考」で未来を見通す 事業を成功に導く意思決定 ~エビデンス・ベースド・マーケティング思考の調査分析で事業に有効な予測手法とは~
2024.11.05 - 2024.11.05