2018-06-09 Halogen の Component を String にできない話の続き
bouzuya/tamaru 。些細な点にこだわりすぎて進んでいない。
昨日 (2018-06-08) の子 Component
の描画に対応しようとしていた。結論から書くと、ぼくにはまだできなかった。 RenderSpec
を雑に実装している点と slamdata/purescript-halogen-vdom-string-renderer を組み合わせている点がまずそうだ。
どこで詰まっているのかを整理するため、ぼくの現状の実装について書く。
halogen は通常 Halogen.VDom.Driver
の runUI
を使用して動かす。これは実 DOM (DOM.HTML.Types.HTMLElement
) に対して指定した Component
を描画し、動かしていく。この runUI
は内部で Halogen.Aff.Driver
の runUI
を使用している。こちらの runUI
へ実 DOM に依存していないので、ぼくはこれを使っている。
ぼくの現在の実装は、この Halogen.Aff.Driver
の runUI
へ実 DOM に依存しない適当な RenderSpec
を与えることで文字列として描画しようとしている。この RenderSpec
の組み立て方がよく分からないのだけど、大切なのは render
くらい。……くらいと書いたが、↓みたいな型になっていて、ぼくみたいのには「よく分からない」以上の感想が出てこない。
render
:: forall s f g p o
. (forall x. InputF x (f x) -> Eff (HalogenEffects eff) Unit)
-> (ComponentSlot h g (Aff (HalogenEffects eff)) p (f Unit) -> Eff (HalogenEffects eff) (RenderStateX r eff))
-> h (ComponentSlot h g (Aff (HalogenEffects eff)) p (f Unit)) (f Unit)
-> Maybe (r s f g p o eff)
-> Eff (HalogenEffects eff) (r s f g p o eff)
これを雑に説明すると↓のとおりだ。
Component
へのQuery
を処理するハンドラー- 子要素を描画するハンドラー
- 要素
- 前の
RenderState
Halogen.VDom.Driver
の runUI
では、これを halogen-vdom でつくれる「実 DOM を更新していく machine 」や描画結果の実 DOM を返す RenderState
で実装している。
ぼくはまともに machine や RenderState
を用意していない。最初に渡される要素を Halogen.VDom.DOM.StringRenderer
の render
に与えていた。
ここまでが現状の実装。で、何が問題なのか。
Halogen.VDom.DOM.StringRenderer
の render
は↓のような型だ。
render ∷ ∀ i w. (w → String) → VDom (Array (Prop i)) w → String
w
というのが halogen-vdom の Widget
だ。ぼくはこれがほとんど使われないものかと思っていたので const ""
という適当な値にしていた。しかし、実際には halogen の子 Component
は ComponentSlot
を使用しており、それはすべて Widget
なのだった。
たぶん、まともに machine を実装し Halogen.VDom.DOM.StringRenderer
を捨てるか、強引に ComponentSlot
をバラして render
する関数 (w -> String
) を実装すればなんとかなると思う。どちらも地獄っぽい。
今日も出かけた。わけあって暑い時間帯に出かけることとなった。暑すぎて、ひどく汗をかいたし、疲れた。
2018-05-31 にも書いたけど、この数週間で土日に出かける頻度が増えており、思ったように進まない。↑も断片的に調べるせいで、何がなんだか分からなくなっている。
おまけに明日も出かけるんだよな……。