2010-02-05 8 views
3

je le code suivant pour générer une page html en blanc avec une série de divs avec son et des classes id dans Haskell en utilisant la bibliothèque Text.XHtml.Strict:problème avec imbrication dans la bibliothèque Text.XHtml avec Haskell

module Main where 

import Text.XHtml.Strict 
import Text.Printf 


page :: Html 
page = pHeader +++ pTop +++ pBody +++ pFooter 

pHeader :: Html 
pHeader = header << thetitle << "Page title" 

pTop :: Html 
pTop = (dC "header") << (dI "title") 

pFooter :: Html 
pFooter = (dC "footer") << (dI "foottext") 

pBody :: Html 
pBody = body << (dC "main") << (dI "window") << (dI "content") 

dC :: String -> Html 
dC x = (thediv noHtml)! [theclass x] 

dI :: String -> Html 
dI x = (thediv noHtml) ! [identifier x] 

main :: IO() 
main = do 
    printf $ prettyHtml $ page 

Les fonctions dC et dI devrait faire un vide avec une classe ou un id respectivement. Dans l'interprète ces fonctions fonctionnent bien quand concaténer, comme dans:

printf $ prettyHtmlFragment $ dC "1" +++ dC "2" 
<div class="1"> 
</div> 
<div class="2"> 
</div> 

Mais pas quand je tente de les imbriquer en utilisant << au lieu de +++, je reçois une erreur:

<interactive>:1:28: 
    Couldn't match expected type `Html -> b' 
      against inferred type `Html' 

ce que je pense que la cause du problème dans la partie principale du code est, mais je ne sais pas comment le réparer. Des idées? DC et cI ne peuvent pas s'immobiliser car ils sont définis comme vides.

Répondre

2

Il suffit de prendre les nohtml parties et modifier les signatures:

dC :: String -> Html -> Html 
dC x = thediv ! [theclass x] 

dI :: String -> Html -> Html 
dI x = thediv ! [identifier x] 

L'opérateur ! peut ajouter attributs non seulement à un objet Html, mais également à une fonction qui renvoie Html. thediv est une fonction qui prend Html et le retourne enveloppé dans un élément <div>. En lui appliquant !, vous créez une fonction qui prend Html et entoure un <div class="…"> (ou id="…").

> :type thediv 
thediv :: Html -> Html 

> let dC c = thediv ! [theclass c] 
> let dI i = thediv ! [identifier i] 

> :type dC 
dC :: String -> Html -> Html 
> :type dI 
dI :: String -> Html -> Html 

> putStr $ prettyHtmlFragment $ body << dC "main" << dI "window" << dI "content" << "Hi" 
<body> 
    <div class="main"> 
     <div id="window"> 
     <div id="content"> 
      Hi 
     </div> 
     </div> 
    </div> 
</body> 

Notez que vous n'avez pas besoin de la parenthèse supplémentaire.

+0

Merci pour cela, la documentation de cette bibliothèque est difficile à trouver (sauf pour la documentation de hackage) et les tutoriels sont pratiquement inexistants. –

+0

Lorsque vous recherchez des documents ou des exemples, souvenez-vous que le package Text.Xhtml était basé sur le package Text.Html et avait presque exactement le même usage. – MtnViewMark

1

Vous devez laisser un trou dans lequel la pièce emboîtée ira. Le trou est exprimé par un paramétrage:

dC classx child = (thediv child)! [theclass classx] 
dI x y = (thediv y) ! [identifier x] 

également pour le corps:

pBody x = body << (dC "main") << (dI "window") << (dI "content" x)