Hexirp / hexirp-hakyll

I decided to deeply fork hakyll.
Apache License 2.0
1 stars 0 forks source link

Hexyll.Core.Provider をリファクタリングする #111

Closed Hexirp closed 4 years ago

Hexirp commented 4 years ago

See https://github.com/Hexirp/hexirp-hakyll/issues/98 .

Provider ディレクトリをつかさどる。補助として Store の作用を使う。

Hexirp commented 4 years ago

うーん、リソースの情報を纏められるという感じかな? リソースの更新日時とかメタデータとか。

Hexirp commented 4 years ago

https://github.com/Hexirp/hexirp-hakyll/blob/fa0f4d089425372951b283432a940c6046a2b9f5/hexyll-core/src/Hexyll/Core/Provider.hs

中核になりそうな関数も色々ある。

Hexirp commented 4 years ago

https://hackage.haskell.org/package/hakyll-4.13.2.0/docs/Hakyll-Core-Provider.html

なるほどなあ?

Hexirp commented 4 years ago

全てのリソースは対応する識別子を持っている。リソースには更新日時がある。リソースにはメタデータが付属している場合もある。メタデータもリソースであり、識別子が付いている。

Hexirp commented 4 years ago

ううむ……ここの作り方が適当だ。

https://github.com/Hexirp/hexirp-hakyll/blob/fa0f4d089425372951b283432a940c6046a2b9f5/hexyll-core/src/Hexyll/Core/Provider/MetadataCache.hs#L25

エラーを握りつぶしている。

Hexirp commented 4 years ago

関連してそうなのは Metadata 作用と Universe 作用と Store 作用である。

Hexirp commented 4 years ago

https://github.com/Hexirp/hexirp-hakyll/blob/fa0f4d089425372951b283432a940c6046a2b9f5/hexyll-core/src/Hexyll/Core/Provider/Internal.hs#L86-L87

ここはどこから来るんだろう? Store かな?

Hexirp commented 4 years ago

Store 作用は type Storable a = (Typeable a, Binary a) である型の値をストアに保存したり読み込む。

Universe 作用は、認識している全ての識別子を読み込むことが出来る。

Metadata 作用は、識別子に付随しているメタデータを読み込むことが出来る。

Hexirp commented 4 years ago

ここでポイントなのは空のメタデータが許されることか?

Hexirp commented 4 years ago

そういえば MetadataEnv を作っていないな。不要だろうけど。

Hexirp commented 4 years ago

空のメタデータはこのようになる。

emptyMetadata :: Metadata
emptyMetadata = Metadata HM.empty
Hexirp commented 4 years ago

Provider 作用の中核になるべきなのは、この二つだろう。

resourceMetadata :: Provider -> Identifier -> IO Metadata
resourceBody :: Provider -> Identifier -> IO String

更新日時の作用とは分離すべきだろう。

Hexirp commented 4 years ago

さらに resourceMetadatagetMetadata と統合される……!

Hexirp commented 4 years ago

つまり、こうなる?

class MonadMetadata m => MonadProvider m where
  getBody :: Identifier -> m String

ああ、それっぽい。出力を String だけに制限するのはどうしたものか。

Hexirp commented 4 years ago

ここでさらに Store 作用を加えるべきか?

Hexirp commented 4 years ago

もしかして Provider って Store を除けば不変なのか?

Hexirp commented 4 years ago

やはりそうだ。 newProvider で生成した後は変化しない。確かに Store もそうっちゃそうだからいいんだけど。

Hexirp commented 4 years ago

うーん、やっぱり内部で Store 作用を利用するので含めよう。

Hexirp commented 4 years ago

関数を一つずつ検索して、必要かどうか確かめていこう。

Hexirp commented 4 years ago

resourceFilePath ってどうして必要なの? identifierPath を使えばいいんじゃない? と思っていたけど、ファイルのパスに providerDirectory を付けるのか。

Hexirp commented 4 years ago
getMetadata :: Identifier -> IO Metadata
resourceMetadata :: Identifier -> IO Metadata

resourceFilePath :: Identifier -> IO FilePath

resourceModificationTime :: Identifier -> IO UTFTime

resourceBody :: Identifier -> IO String

こういう風に色々な情報を取得できるようになっているんだな。

Hexirp commented 4 years ago

メタデータについてもっと考えないといけない。リソースには必ずメタデータが付いていると MonadMetadata により設定されている。それで Metadata はリソースなのか。識別子がつくのか。

Hexirp commented 4 years ago

嘘でしょ? メタデータの形式がここでハードコーディングされている。

https://github.com/Hexirp/hexirp-hakyll/blob/fa0f4d089425372951b283432a940c6046a2b9f5/hexyll-core/src/Hexyll/Core/Provider/Metadata.hs

Hexirp commented 4 years ago

こんなの意味がない。メタデータもコンパイラーで取得するようにしよう。

Hexirp commented 4 years ago

全てがリソースである、つまり全てに識別子が付く主義を取ると、メタデータのメタデータのメタデータという困ったことが起きる。

Hexirp commented 4 years ago

コンパイラの途中のデータもリソースと捉えるべきか? 分からない。

Hexirp commented 4 years ago

https://github.com/Hexirp/hexirp-hakyll/blob/fa0f4d089425372951b283432a940c6046a2b9f5/hexyll-core/src/Hexyll/Core/Provider/Internal.hs#L128

ここがメタデータがリソースとして扱われているらしき場所……かと思ったけど違うみたい?

Hexirp commented 4 years ago

https://github.com/Hexirp/hexirp-hakyll/blob/fa0f4d089425372951b283432a940c6046a2b9f5/hexyll-core/src/Hexyll/Core/Provider/Internal.hs#L64

ここで致命的にそうなってる。

Hexirp commented 4 years ago

識別子 (Identifier) とファイルパス (FilePath) の混同か?

Hexirp commented 4 years ago

Hexyll はリソースという概念を中心として動く。

Hexirp commented 4 years ago
Hexirp commented 4 years ago

別のモデルとして……

Hexirp commented 4 years ago

そして

Hexirp commented 4 years ago
Hexirp commented 4 years ago

https://github.com/Hexirp/hexirp-hakyll/blob/fa0f4d089425372951b283432a940c6046a2b9f5/hexyll-core/src/Hexyll/Core/Compiler/Internal.hs#L135

何かを要求するときは、何が必要なのだろうか? 生の文字列? コンパイラー結果? 前者だろうな。

Hexirp commented 4 years ago

いや、コンパイラーの結果だ。それは SomeItem で抽象化される。

https://github.com/Hexirp/hexirp-hakyll/blob/fa0f4d089425372951b283432a940c6046a2b9f5/hexyll-core/src/Hexyll/Core/Runtime.hs#L108

一つのリソースに一つのコンパイラーが対応する……。

Hexirp commented 4 years ago

コンパイラーの多重化は identifierVersion で実現されるのだろうか……?

Hexirp commented 4 years ago

纏めようか?

Hexirp commented 4 years ago

resourceInfoMetadata は内部でしか使われていない。

Hexirp commented 4 years ago

だが、メタデータの取得の形式も自由にしたいので、メタデータもリソースとすることにする。

Hexirp commented 4 years ago
Hexirp commented 4 years ago

んんん……? 「メタデータに対応するリソースには更新日時が存在する」は、メタデータが別のファイルとして存在する形式 a.txt.metadata に対応するためか?

Hexirp commented 4 years ago

たとえば、 index.md をコンパイルするのに index.md のメタデータが必要としよう。 index.md のコンパイラーは index.md (metadata) のコンパイル結果に依存する。 index.md (metadata) のコンパイラーは生の index.md が必要かもしれないし生の index.md.metadata が必要かもしれない。

Hexirp commented 4 years ago

MonadProvider はファイルに対応するリソースを扱うモナドであり……メタデータに関する機構はより高機能な箇所……つまり、コンパイラーなどで実装される。

Hexirp commented 4 years ago

MonadUniverse はどうするか……。ファイルに対応するリソースが全てであるならば MonadProvider が継承する道理はあるが。

しかし、そうではない。新しいリソースが登場する可能性がある。

Hexirp commented 4 years ago

https://github.com/Hexirp/hexirp-hakyll/blob/fa0f4d089425372951b283432a940c6046a2b9f5/hexyll-core/src/Hexyll/Core/Provider/Internal.hs#L170

ここは私の考察の裏付けになるな……

MonadProvider において Identifier は不要であり Path Rel File で十分。

Hexirp commented 4 years ago

Ident と略するのをやめようか。

Hexirp commented 4 years ago

H.C.Metadata のそもそもの設計が悪い可能性が?