Expression Problem を解決する | try! Swift Tokyo 2018 Day2-1

UIKitでは、一連の UIView と UIView のサブクラスをまとめてビュー階層を記述します。UIViewをサブクラス化することによって自分自身のビューを作成することもできます。しかし、この View Description をAppKitやシリアライゼーションに再利用することはできません。UIKit と似たようなものに EnumKit があり、 View は列挙型のケースとして提供されています。これで View Description を使いまわすことができますが、EnumKit なしで (もしくはライブラリをフォークしないと)ビューを生成することができません。

'Final Tagless' は、Swift のプロトコルの内部にある強力な Self 型を用いて、双方の世界をベストな状態にします。

Expression Problem を解決する

f:id:niwatako:20180302095637j:plain

このモックアップを見て下さい、どうやって作るのか

ボタンとスタックビュー

f:id:niwatako:20180302095841j:plain

全部UIViewですね

じっくり見ると真ん中はMapViewかもしれないですね。カスタムかもしれないです。

f:id:niwatako:20180302095909j:plain

UIViewをサブクラス化すればいいですね

これは素晴らしいことです。UIKitの外側でアプリを作ることができる。

Macアプリを作るには?同じプロセスをNSViewとNSButtonで同じことをする必要がある。

またWebでも同じように作らなければいけない

f:id:niwatako:20180302100012j:plain

この一つのビュー階層の表現が複数のプラットフォームにトランスフォームできればいいですよね?

でもそれはできるはずです本来。

これは一般的な問題を特定の例で説明している例であって、エクスプレッションプロブレムということです。

f:id:niwatako:20180302100058j:plain

カスタマイズが難しい。新しいヴューの表現を作るのが難しい

関数プログラミングのコミュニティで補問題になっている。Swiftではどうしたらうまくいくのか

今日はついにこれを解決していきましょう

f:id:niwatako:20180302100138j:plain

サブクラス化はうまくいかない。UIKitがサブクラスで問題が起きた時にViewヒエラルキーに反映されない

Enumはどうでしょう 問題が起きる

これらを解明することでソリューションが何なのか対応できるかが分かる。

EnumKitを考えます

f:id:niwatako:20180302100233j:plain

特定のケースはUIVeiwの特定のサブクラスになります

f:id:niwatako:20180302100250j:plain

case は必要なプロパティです。

別のビューが中には言っている、Viewを再帰的に使う、だから再帰的である必要があります。

f:id:niwatako:20180302100309j:plain

2つのボタンを考えてみましょう

f:id:niwatako:20180302100336j:plain

f:id:niwatako:20180302100345j:plain

意味を与えるために再帰的トラバーサルをくわえます

f:id:niwatako:20180302100411j:plain

f:id:niwatako:20180302100428j:plain

f:id:niwatako:20180302100436j:plain

UIKitを割り当てていく

f:id:niwatako:20180302100452j:plain

NSViewも

とは言え問題は発生する

f:id:niwatako:20180302100510j:plain

f:id:niwatako:20180302100515j:plain

あたらしいViewをどう追加するか newViewのようなのを追加するのは良くない

f:id:niwatako:20180302100529j:plain

両方を解決する必要があります

f:id:niwatako:20180302100619j:plain

f:id:niwatako:20180302100629j:plain

非網羅的Enumを使うのも考えて良いと思います。モジュールの外でextensionしてカスタマイズする

f:id:niwatako:20180302100700j:plain

f:id:niwatako:20180302100749j:plain

f:id:niwatako:20180302100753j:plain

でもdefaultケースが必要になってしまいます。ここでまた困ってしまいます。

プロトコルを考えましょう

f:id:niwatako:20180302100812j:plain

f:id:niwatako:20180302100818j:plain

Viewから間接的なViewがある

Viewプロトコル

f:id:niwatako:20180302100839j:plain

staticなメソッドとしてそれぞれのボタンが

f:id:niwatako:20180302100906j:plain

StackViewには子供のViewがある

Selfに目を向けましょう

f:id:niwatako:20180302100929j:plain

REALTypeがSelfに置き換えられます

f:id:niwatako:20180302100951j:plain

追加する時はプロトコルを追加しましょう

f:id:niwatako:20180302100957j:plain

階層構造をどう作ればよいでしょうか

f:id:niwatako:20180302101015j:plain

Genericな関数を考えます

f:id:niwatako:20180302101035j:plain

f:id:niwatako:20180302101048j:plain

EnumではうまくいかなかったfullVeiwを考えます

f:id:niwatako:20180302101107j:plain

f:id:niwatako:20180302101127j:plain

意味は与えてないがVeiwのDescriptionです

UIKitのパワーを取り戻しましょう

f:id:niwatako:20180302101145j:plain

f:id:niwatako:20180302101208j:plain

f:id:niwatako:20180302101211j:plain

f:id:niwatako:20180302101218j:plain

f:id:niwatako:20180302101230j:plain

f:id:niwatako:20180302101255j:plain

もしこれをGoogleで検索してもっと知りたいなら

f:id:niwatako:20180302101319j:plain

Final Tagless Styleで検索してみて下さい。

Expression Probremはもっと奥深いです

キャンバス上のダイアグラムを考えましょう 様々な形状があり階層構造にしていく

f:id:niwatako:20180302101416j:plain

副作用があります、Itemが副作用そのもの

f:id:niwatako:20180302101452j:plain

f:id:niwatako:20180302101527j:plain

問題は拡張性の問題で2つでした、新しいアイテムを作る Final Tagless Approachはかいけつしてくれました。

f:id:niwatako:20180302101602j:plain

もっと学ぶにはこちらです

f:id:niwatako:20180302101608j:plain

f:id:niwatako:20180302101643j:plain

[広告]面白かったら、ためになったら

  • はてなブックマークSwift タグをつけてブックマーク!
  • 「インターネットで生活を楽しく豊かにしたい」仲間を募集しています
  • Bitcoin: 3KGqXtR1ZaGVdkvcw8CCNrkDxDhdbZBYHL