2016-08-06 4 views
3

このマップは、GTypeとそのGTypeのインスタンスをIOストリングに変換する関数の間にあります。私は要素をとり、その要素の文字列表現を取得する関数を作成しています。タイプをIOストリングに変換する機能を持つGTypeのマップ

mapping = 
    [ (Types.gTypeHTMLSourceElement, HTMLSourceElement.getSrc ) 
    , (Types.gTypeHTMLObjectElement, HTMLObjectElement.getData ) 
    , (Types.gTypeHTMLTimeElement , HTMLTimeElement.getDateTime) 
    , (Types.gTypeHTMLElement  , HTMLElement.getInnerText ) 
    , ... 
    ] 

は、このエラーを与える:

Couldn't match type ‘HTMLObjectElement’ with ‘HTMLSourceElement’ 

私はghcjs-DOMを使用しています。このコードをエラーなくコンパイルするにはどうすればよいですか?私は正しい方法で問題に近づいていますか?

誰かがアレクの答えよりも優れた答えを思い付けることができるなら、私は彼らの答えを受け入れるでしょう。

+0

これは正しい方法ではないと思いますが、これをコンパイルするには 'RankNTypes'が必要で、' mapping :: [(GType、forall a IO(a - >文字列))] '。 – Alec

+0

@Alecそれに近づくためのより良い方法は?ノード名に基づいて切り替えた場合、タイプセーフではありません。 – 2426021684

+0

私のコメントを読み返すと、実際には 'mapping :: [(GType、forall a .-> IO String))]'を読んでいるはずです。しかし、あなたの質問に関しては、私は最良の方法は何だろうか分かりません...私はあなたが 'class Contents a where {getContents :: a - > IO String}'を作成し、次にインスタンスをインスタンス化すると思います。Contents HTMLSourceElementどこで{getContents = HTMLSourceElement.getSrc} '。 – Alec

答えて

0

私は問題にアプローチする正しい方法は、GTypeに基づいて分岐を行う機能をtoStringにすることだと思います。

toString :: GObjectClass obj => obj -> IO String 
toString obj | obj `isA` gTypeHTMLSourceElement = getSrc . castToHTMLSourceElement 
      | obj `isA` gTypeHTMLObjectElement = getData . castToHTMLObjectElement 
      | obj `isA` gTypeHTMLTimeElement = getDateTime . castToHTMLTimeElement 
      | obj `isA` gTypeHTMLElement = getInnerText . castToHTMLElement 
      | ... 
+0

Downvoterがあった場合は、ダウン投票を正当化してもらえますか?私はフィードバックに興味があるだろう... – Alec

関連する問題