| 1 |
type Bib = [ Book* ]
|
| 2 |
type Book = <book>[ Title Subtitle? Author+ ]
|
| 3 |
type Title = <title>[ PCDATA ]
|
| 4 |
type Subtitle = <subtitle>[ PCDATA ]
|
| 5 |
type Author = <author>[ PCDATA ]
|
| 6 |
|
| 7 |
let title(Book -> String) <book>[ <title>x _* ] -> x
|
| 8 |
|
| 9 |
(* We annotate each book with a printing function for it *)
|
| 10 |
|
| 11 |
type FBook = Book -> String
|
| 12 |
type ABook = <book print=FBook>[ Title Subtitle? Author+ ]
|
| 13 |
type ABib = [ ABook* ]
|
| 14 |
(* Note that: ABook <= Book, ABib <= Bib *)
|
| 15 |
|
| 16 |
let set(<book>c : Book)(f : FBook) : ABook = <book print=f>c
|
| 17 |
let prepare(b : Bib) : ABib = map b with x -> set x title
|
| 18 |
|
| 19 |
(* We display the annotated bibliography *)
|
| 20 |
|
| 21 |
type Ul = <ul>[ Li+ ]
|
| 22 |
type Li = <li>[ PCDATA ]
|
| 23 |
|
| 24 |
let display (ABib -> Ul; ABook -> Li)
|
| 25 |
| <book print=f>_ & x -> <li>(f x)
|
| 26 |
| [] -> raise "Empty bibliography"
|
| 27 |
| p -> <ul>(map p with z -> display z)
|
| 28 |
|
| 29 |
(* We change the dispay function for some books *)
|
| 30 |
|
| 31 |
let change(p : Book -> Bool)(f : FBook)(b : ABib) : ABib =
|
| 32 |
map b with x -> if (p x) then set x f else x
|
| 33 |
|
| 34 |
type HasSub = <_>[ _* Subtitle _* ]
|
| 35 |
|
| 36 |
let change_if_sub =
|
| 37 |
change (fun (Book -> Bool) HasSub -> `true | _ -> `false)
|