GHCJSのスタブを使うのは大変っぽい
昨日のghc-base-stubを使う方式だと上手くいかなかった。
GHCJSに再度トライ - ログ日記
例えばghcjs-domを使いたい場合、GHCJSだと ghcjs-dom, ghcjs-dom-jsffi を使うところが
GHC版だと ghcjs-base-stub, ghcjs-dom, ghcjs-dom-jsaddle, jsaddle-dom, jsaddle を使うことになる。
これで一旦はコンパイルが通るんだけども、GHCJS版とGHC版でDOMの型が違うっぽい。
GHCJS版
https://raw.githubusercontent.com/ghcjs/ghcjs-dom/master/ghcjs-dom-jsffi/src/GHCJS/DOM/Types.hs
type JSM = IO -- | This is the same as 'JSM' except when using ghcjs-dom-webkit with GHC (instead of ghcjs-dom-jsaddle) type DOM = IO -- | The 'MonadJSM' is to 'JSM' what 'MonadIO' is to 'IO'. -- When using GHCJS it is 'MonadIO'. type MonadJSM = MonadIO -- | This is the same as 'MonadJSM' except when using ghcjs-dom-webkit with GHC (instead of ghcjs-dom-jsaddle) type MonadDOM = MonadIO -- | The 'liftJSM' is to 'JSM' what 'liftIO' is to 'IO'. -- When using GHCJS it is 'liftIO'. liftJSM :: MonadJSM m => JSM a -> m a liftJSM = liftIO -- | This is the same as 'liftJSM' except when using ghcjs-dom-webkit with GHC (instead of ghcjs-dom-jsaddle) liftDOM :: MonadDOM m => DOM a -> m a liftDOM = liftIO
こんな感じで普通のIOになっている。
ghcjs-dom-jsaddleでは
JSDOM.Types as GHCJS.DOM.Types
のようになっていて、その定義は
https://raw.githubusercontent.com/ghcjs/jsaddle-dom/master/src/JSDOM/Types.hs
-- | This is the same as 'JSM' except when using ghcjs-dom-webkit with GHC (instead of ghcjs-dom-jsaddle) type DOM = JSM -- | This is the same as 'JSContextRef' except when using ghcjs-dom-webkit with GHC (instead of ghcjs-dom-jsaddle) type DOMContext = JSContextRef -- | This is the same as 'MonadJSM' except when using ghcjs-dom-webkit with GHC (instead of ghcjs-dom-jsaddle) type MonadDOM = MonadJSM -- | This is the same as 'liftJSM' except when using ghcjs-dom-webkit with GHC (instead of ghcjs-dom-jsaddle) liftDOM :: MonadDOM m => DOM a -> m a liftDOM = liftJSM -- | This is the same as 'askJSM' except when using ghcjs-dom-webkit with GHC (instead of ghcjs-dom-jsaddle) askDOM :: MonadDOM m => m DOMContext askDOM = askJSM -- | This is the same as 'runJSM' except when using ghcjs-dom-webkit with GHC (instead of ghcjs-dom-jsaddle) runDOM :: MonadIO m => DOM a -> DOMContext -> m a runDOM = runJSM
全てJSMを使うようになっている。
JSMは
https://github.com/ghcjs/jsaddle/blob/master/jsaddle/src/Language/Javascript/JSaddle/Types.hs
ここで GHCJSの場合はIOにしているけれども、GHCの場合はIOと似ているが異なる型になるようだ。
GHCを使う場合には、JSMとIOは変換できないっぽい。
もしかすると、ghcjs-base-stubのように、ghcjs-dom-stubとかを作っていけば良いのかもしれないが、大量に型があって自分で作るのはつらい。
別の方法を考える。
ーーーー
ここまで書いて、ちょっとサンプルを作った。
github.com
type JSM = IO 版。
自動生成されたコードが何万行もあってつらい…。
正規表現置換で一気にいけるところは変更して、無理なところは手動でぽちぽちやった。
折角なので開発中にJSMをprintしたら分かりやすいメッセージを出すようなスタブが出来れば良かったんだけど、自動生成じゃないと無理そう。普通にjsaddleを使うかね…。
少ししか(と言っても数万行)書いてないのに既にコンパイル重くなってきたしね。
型だけ見るなら
{-# LANGUAGE CPP #-} module FormSample where import Control.Monad import Control.Monad.IO.Class (MonadIO (..)) import Control.Monad.Trans.Class (lift) import Control.Monad.Trans.Maybe (MaybeT (..), runMaybeT) import GHCJS.DOM import GHCJS.DOM.Document import GHCJS.DOM.HTMLCollection import GHCJS.DOM.Types import Language.Javascript.JSaddle.Debug formEl :: MaybeT JSM Element formEl = do doc <- MaybeT currentDocument forms <- getForms doc form <- MaybeT $ namedItem forms "form" return form someProcess = undefined app :: JSM () app = do mform <- runMaybeT formEl case mform of Just a -> someProcess a Nothing -> undefined return () #ifdef MIN_VERSION_ghcjs_dom_jsffi runForm :: IO () runForm = app #else runForm :: IO () runForm = runOnAll_ app #endif
jsaddleのデバッグ用関数(?)runOnALLが使える。実行しても特に何も起こらない。