type Biblio = [Heading Paper*];; type Heading = [ PCDATA ];; type Paper = [Author+ Title Conference File];; type Author = [ PCDATA ];; type Title = [ PCDATA ];; type Conference = <conference>[ PCDATA ];; type File = <file>[ PCDATA ];; type Html = <html>[Head? Body];; type Head = <head>[ <title>[ PCDATA ] ];; type Body = <body>[Mix*];; type Mix = <h1>[Mix*] | <a href=String>[Mix*] | <p>[Mix*] | <em>[Mix*] | <ul>[ <li>[Mix*] +] | Char;; let fun do_authors ([Author+] -> [Mix*]) | [ <author>a ] -> a | [ <author>a <author>b ] -> a " and, " b | [ <author>a; x] -> a ", " (do_authors x) in let fun do_paper (Paper -> <li>[Mix*]) <paper>[ x::(_* ) <title>t <conference>c <file>f ] -> (* Here, type inference says: x : [Author+] ... *) let authors = do_authors x in <li>([ <a href=f>t ] authors "; in " [ <em>c ] "." ) in let fun do_biblio (Biblio -> Html) <bibliography>[ <heading>h; p ] -> let body = match p with | [] -> "Empty bibliography" | l -> [ <h1>h <ul>(map l with x -> do_paper x) ] in <html>[ <head>[ <title>h ] <body>body ] in let bib : Biblio = <bibliography>[ <heading>"Alain Frisch's bibliography" <paper>[ <author>"Alain Frisch" <author>"Giuseppe Castagna" <author>"Véronique Benzaken" <title>"Semantic subtyping" <conference>"LICS 02" <file>"semsub.ps.gz" ] <paper>[ <author>"Mariangiola Dezani-Ciancaglini" <author>"Alain Frisch" <author>"Elio Giovannetti" <author>"Yoko Motohama" <title>"The Relevance of Semantic Subtyping" <conference>"ITRS'02" <file>"itrs02.ps.gz" ] <paper>[ <author>"Véronique Benzaken" <author>"Giuseppe Castagna" <author>"Alain Frisch" <title>"CDuce: a white-paper" <conference>"PLANX-02" <file>"planx.ps.gz" ] ] in do_biblio bib ;;