capability
外部との関係をinterfaceとして定義する
もたぶんほとんど同じ意味
任意のモナドに対しをinstanceにする
1つの型クラスに定義するmethodをまとめて「1機能」と呼ぶ感じ
ある程度同じ文脈のmethod群を1つの機能として、型クラスとして定義する
いや、若干違いそうmrsekut.icon
Haskell Cakeで言うところのAppMがApplication Monadで
Layer 2で定義する外部依存関係との関係を定義したモナドがcapability
基本的にmonadを継承した型クラスのみのことを指す
つまり、具体的な実装はなくinterfaceのみを提供する
そのため、かなり抽象的に書く必要がある
具体例をいくつか見てみないと、理想的な抽象度を知るまでコツが要りそうmrsekut.icon
永続性にアクセスすることを表すクラスは、
RESTとかLocalStarageみたいな型クラス名を使うのではなく、
GetPublicResourceのような抽象的なものとして定義する
GetPublicResourceとして使って、その先のものが交換可能であるように心がける
capabilityを使用すると、システム内のアクションの純粋関数を記述できる
これらの関数を実行するには、最終的にEffectが必要になる
それらを使用して、エフェクトをシステムの外縁までプッシュすることができる
よくわからにmrsekut.icon
HTTPを介したREST API
Local Strage
Loging
browserのwindow object
コード片とそのコメントを読むとわかる
認証の段階によって型クラスをわけ、さらに継承関係があることがわかる
最初のGetPublicResourceは認証無しで実行できるcapability
Authenticationは認証を管理するもの
credentialsをread/wrigteできることを表す
この並びではこれだけ少し浮いているmrsekut.icon
GetAuthResourceは認証情報を取得するもの
Authenticaionを継承する
read only
ManageAuthResourceは、リソースを更新するcapability
認証済みである必要があることを、GetAuthResourceを継承することで表現
read and write
この辺(Capbabilityディレクトリ)ってHaskell Cakeとかのどれに該当するの #?? layer 2?
LogMessagesの実装
これは恐らくRealWorldには存在しないが、Haskell Cakeとかの題材として実装されている
ProdとDevでlogの内容を変えたい、という要件がある
これをStoreで管理して、ReaderTパターンで扱う
どこにLogを記録するかは、capability上では一般化されている
外部サービスでもconsoleでも良い
AppMに全ての具体的なcapbabilityの実装をする
これがlayer 1かなmrsekut.icon
readerTパターンを使う
AppMがその具体的なMonad
このモナドは読み取り専用、IORef的なやつになる
EnvはこのPRでStoreにrenameされている Storeがglobalな環境になる
AppMとrunAppMの定義と、Monadなどのderivingは恐らく定型文になる
Effectを2つに分類する
monadを追加した事自体によって可能になる操作(?)
intrinsic effects provide operations enabled by the additional structure of the monad itself.
例えば
StateTのinstrinsic effectsは、状態を追加すること
ConsuitMのソレは、streamingを追加すること
capabilities
Effectである
手動かReaderT経由でMonadにcontextを渡す事ができる
実装はBase Monadのinstrinsic effectsに依存することがある
全てのEffectはできる限りcapablitiyとして、無理ならinstricsic effectsとして作る
これcapabilityの考え方から逆にReaderTパターンを導いているのかmrsekut.icon
なるほど
具体例