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 にも書いたけど、この数週間で土日に出かける頻度が増えており、思ったように進まない。↑も断片的に調べるせいで、何がなんだか分からなくなっている。
おまけに明日も出かけるんだよな……。