examples.ml 10.8 KB
Newer Older
1

2
let examples = [ "functions","(* Simple functions can be defined this way: *)
3
4
5
let f1 (x : Int) : Int = x + 3
;;
f1 5
6
7

(* With several arguments: *)
8
9
10
let f2 (x : Int, y : Int) : Int = x + y
;;
f2 (10,20)
11
12

(* You may directly deconstruct the arguments: *)
13
14
15
type A = <a href=String>String
let f3 (<a href=url>txt : A) : String = url @ \"=>\" @ txt
;;
16
17
18
19
20
21
f3 <a href=\"http://www.cduce.org\">\"CDuce homepage\";;

(* In general, if you want to specify several arrow types, or
   use several pattern matching branches, you have the general
   form: *)

22
let f4 (A -> String; ['0'--'9'+] -> Int)
23
| x & A -> f3 x
24
25
26
| x -> int_of x
;;
f4 \"123\"
27
";"mutrec","(* Adjacent type declarations are mutually recursive *)
28
29
30
type T = <t>S
type S = [ (Char | T)* ]
let x : S = [ 'abc' <t>['def'] 'ghi' ]
31

32
(* Similarly for toplevel function definitions *)
33

34
35
36
37
let f (x : Int) : Int = g x
let g (x : Int) : Int = 3
let a = 2
let h (x : Int) : Int = f x
38
   (* f and g are mutually recursive, but they cannot use h *)
39
";"sequence","(* Sequence are just defined with pairs and the atom `nil;
40
   the following notation are equivalent: *)
41
42
43
let l1 = (1,2,3,`nil)
let l2 = (1,(2,(3,`nil)))
let l3 = [ 1 2 3 ]
44
45

(* The [...] notation allow to specify a tail after a semi-colon : *)
46
47
let l4 = (10,20,l1)
let l5 = [ 10 20 ; l1 ]
48
49

(* Concatenation @ *)
50
let l6 = [ 1 2 3 ] @ [ 4 5 6 ]
51
52

(* Inside [...], it is possible to escape a subsequence with a ! *)
53
let l7 = [ 1 2 !l6 !l1 5 ]
54
";"seqtypes","(* Sequence types are defined with regular expression over types *)
55
56
57
type IntList = [ Int* ]
type IntStringList = [ (Int String)* ]
type IntNonEmptyList = [ Int+ ]
58

59
let l : IntList = [ 1 2 3 ]
60
";"integers","(* Yes, CDuce can handle large integers! *)
61
let facto (Int -> Int)
62
63
64
 | 0 | 1 -> 1
 | n -> n * (facto (n - 1))
in
65
facto 300
66
67

(* The tail-recursive way *)
68
let facto ((Int,Int) -> Int)
69
70
71
 | (x, 0 | 1) -> x
 | (x, n) -> facto (x * n, n - 1)
in
72
facto (1,10000)
73
";"sumtype","type Expr = 
74
75
76
77
    (`add, Expr, Expr)
  | (`mul, Expr, Expr)
  | (`sub, Expr, Expr)
  | (`div, Expr, Expr)
78
  | Int
79
 
80
let eval ( Expr -> Int )  
81
82
83
  | (`add,x,y) -> eval x + eval y
  | (`mul,x,y) -> eval x * eval y
  | (`sub,x,y) -> eval x - eval y
84
  | (`div,x,y) -> (eval x) div (eval y)
85
86
  | n -> n 
in
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
eval (`add, 10, (`mul, 20, 5))
";"ovfun","type Person = FPerson | MPerson 
type FPerson = <person gender = \"F\" >[ Name Children (Tel | Email)?] 
type MPerson = <person gender=\"M\">[ Name Children (Tel | Email)?] 
type Children = <children>[Person*] 
type Name = <name>[ PCDATA ]
type Tel = <tel kind=?\"home\"|\"work\">['0'--'9'+ '-' '0'--'9'+]
type Email = <email>[PCDATA '@' PCDATA]

type Man = <man name=String>[ Sons Daughters ]
type Woman = <woman name=String>[ Sons Daughters ]
type Sons = <sons>[ Man* ]
type Daughters = <daughters>[ Woman* ]

let split (MPerson -> Man ; FPerson -> Woman)
  <person gender=g>[ <name>n <children>[(mc::MPerson | fc::FPerson)*]; _] ->
     let tag = match g with \"F\" -> `woman | \"M\" -> `man in
     let s = map mc with x -> split x in
     let d = map fc with x -> split x in
     <(tag) name=n>[ <sons>s  <daughters>d ] 
 
108
109

let base : Person = 
110
111
<person gender=\"F\">[ 
  <name>\"Themis\"
112
  <children>[ 
113
114
    <person gender=\"M\">[
      <name>\"Prometheus\"
115
      <children>[
116
117
118
119
120
121
122
123
124
125
126
        <person gender=\"M\">[
          <name>\"Deucalion\"
          <children>[]
        ]
      ]
      <email>\"focifero@olympus.com\"
    ] 
    <person gender=\"M\">[
      <name>\"Epimetheus\"
      <children>[]
      <tel> \"314-1592654\"
127
128
129
130
    ]
  ] 
  <tel kind=\"home\"> \"271-828182\"
]
131
132
133
134
135
136
in
split base
";"note","type Doc = <doc>Text
type Text = [ (Char | (Letter+ ' '* Note))* ]
type Letter = 'a'--'z' | 'A'--'Z'
type Note = <note>[ PCDATA ]
137

138
139
140
type Flow = [ (Char | <ref no=Int>[ PCDATA ])* ]
type Notes = [ <note no=Int>[ PCDATA ]* ]
type Result = <doc>[ <body>Flow <notes>Notes ]
141

142
let format (<doc>s : Doc) : Result = 
143
  let (body,notes) = text (s,1) in
144
  <doc>[ <body>body <notes>notes ]
145

146
let text ( (Text,Int) -> (Flow,Notes) )
147
148
149
150
 | ([ pre::Char*? (word::Letter+ ' '* <note>n); rem ], count) ->
      let (body,notes) = text (rem, count + 1) in
      (pre @ [<ref no=count>word] @ body, 
       [<note no=count>n] @ notes)
151
 | (body,_) -> (body, [])
152
153
154

let src : Doc = <doc>[ 'CDuce ' <note>\"Frisch, Castagna, Benzaken\"
		 ' is an XML ' <note>\"a W3C standard\"
155
156
157
158
159
160
161
162
163
164
		 '-friendly programming language.' ]
in
format src
";"biblio","type Biblio  = <bibliography>[Heading Paper*]
type Heading = <heading>[ PCDATA ]
type Paper   = <paper>[ Author+ Title Conference File ]
type Author  = <author>[ PCDATA ]
type Title   = <title>[ PCDATA ]
type Conference = <conference>[ PCDATA ]
type File    = <file>[ PCDATA ]
165
166

(* Simplified HTML *)
167
type Html  = <html>[ <head>[ <title>[ PCDATA ] ]  <body>Mix ]
168
type Mix   = [ ( <h1>Mix | <a href=String>Mix | <p>Mix | <em>Mix 
169
	       | <ul>[ <li>Mix +] | Char )* ]
170

171
let do_authors ([Author+] -> Mix)
172
173
 | [ <author>a ] -> a
 | [ <author>a <author>b ] -> a @ \" and, \" @ b
174
 | [ <author>a; x] -> a @ \", \" @ (do_authors x)
175

176
let do_paper (Paper -> <li>Mix)
177
  <paper>[ x::_* <title>t <conference>c <file>f ] ->
178
    <li>[ <a href=f>t !(do_authors x) '; in ' <em>c '.' ]
179

180
let do_biblio (Biblio -> Html)
181
182
183
184
185
  <bibliography>[ <heading>h; p ] ->
      let body = match p with
      | [] -> \"Empty bibliography\"
      | l -> [ <h1>h <ul>(map l with x -> do_paper x) ]
      in    
186
      <html>[ <head>[ <title>h ] <body>body ]
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215

let bib : Biblio = 
  <bibliography>[
    <heading>\"Alain Frisch's bibliography\"
    <paper>[
      <author>\"Alain Frisch\"
      <author>\"Giuseppe Castagna\"
      <author>\"Vronique 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>\"Vronique Benzaken\"
      <author>\"Giuseppe Castagna\"
      <author>\"Alain Frisch\"
      <title>\"CDuce: a white-paper\"
      <conference>\"PLANX-02\"
      <file>\"planx.ps.gz\"
    ]
216
217
218
 ]
in
do_biblio bib
219
";"projection","(* The projection  e/t   is translated to:
220
221
   transform e with [ (x::t|_)* ]  -> x *)

222
223
224
225
226
227
228
type Biblio  = <bibliography>[Heading Paper*]
type Heading = <heading>[ PCDATA ]
type Paper   = <paper>[ Author+ Title Conference File ]
type Author  = <author>[ PCDATA ]
type Title   = <title>[ PCDATA ]
type Conference = <conference>[ PCDATA ]
type File    = <file>[ PCDATA ]
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257

let bib : Biblio = 
  <bibliography>[
    <heading>\"Alain Frisch's bibliography\"
    <paper>[
      <author>\"Alain Frisch\"
      <author>\"Giuseppe Castagna\"
      <author>\"Vronique 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>\"Vronique Benzaken\"
      <author>\"Giuseppe Castagna\"
      <author>\"Alain Frisch\"
      <title>\"CDuce: a white-paper\"
      <conference>\"PLANX-02\"
      <file>\"planx.ps.gz\"
    ]
258
 ]
259

260
261
262
let titles = [bib]/<paper>_/<title>_
let authors = [bib]/<paper>_/<author>_
let titles_concat = [bib]/<paper>_/<title>_/Char
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
";"xtransform","
(* For the purpose of the example we can consider this hugely
   simplified definition of Xhtml
*)

type Flow = Char | Block | Inline  ;;
type Block = P | Heading | Lists | Blocktext | Char
type Lists = Ul
type Blocktext = Pre |  Address | Center;;
type Inline = Char | A | Fontstyle
type Fontstyle = Tt | I | B | Big | Small;;

type Xhtml = <html>[ Head Body ];;
type Head = <head>[ Title <link>[ ]];;
type Title = <title>[ PCDATA ];;
type Body = <body bgcolor=?String>[ Block* ];;

type P = <p>[ Inline* ];;
type Heading = <(`h1 | `h2 | `h3 | `h4)>[ Inline* ];;

type Ul = <ul>[Li+];;
type Li = <li>[ Flow* ];;

type Address = <address>[ Inline* ];;
type Pre = <pre>[ (PCDATA | A | Fontstyle)* ];;
type Center = <center>[ Block* ];;

type A = <a ({ name = String } | { href = String })>[ (Inline \ A)* ];;
type Tt = <tt>[ Inline* ];;
type I = <i>[ Inline* ];;
type B = <b>[ Inline* ];;
type Big = <big>[ Inline* ];;
type Small = <small>[ Inline* ];;


(* xtransform matches the patterns against the root element of each
   XML tree and, if it fails, it recursively applies itself to the
   sequence of sons of the root.

   It can be used to put in boldface all the links of an XHTML
   document as follows
*)

let bold(x:[Xhtml]):[Xhtml]=xtransform x with <a (y)>t -> [ <a(y)>[<b>t] ]


(* let us apply the function to a document where links appear
   at different depths
*)


let doc : Xhtml =
  <html>[
    <head>[<title>\"Example\" <link>[]]
    <body>[
      <h2>['You can have links ' <a href=\"here\">\"here\"]
      <pre>['Or they can be down']
      <ul>[
        <li>['In ' <a name=\"list\">\"lists\" ' for instance']
	<li>['or you oddly decided to ' 
             <center>[<p>[<a href=\"what?\">\"center\"]] 
             ' them '
            ]
      ]
      <address>[
        'and even if they are in fancy ' <a name=\"address\">\"address boxes\"
      ]
      <p>[
          'nevertheless ' <a href=\"http://www.cduce.org\">\"Cduce\" ' and '
          <a href=\"xtransform\">[<tt>\"xtransform\"] 
          ' will put all links in bold so that when'
          ' you program your transformation you '
          <big>[<a name=\"\">\" don\'t \" ] ' have to worry about it'
     ]
   ]
  ];;

bold [doc];;

let [x] = bold [doc] in print_xml x;;
343
"; ]
344
let present = "<ul><li><a href=\"/cgi-bin/cduce?example=functions\">Functions.</a> 
345
Several syntaxes to define functions.
346
</li><li><a href=\"/cgi-bin/cduce?example=mutrec\">Mutual recursion.</a> 
347
Mutual toplevel definition for types and functions.
348
</li><li><a href=\"/cgi-bin/cduce?example=sequence\">Sequence literals.</a> 
349
How to write sequences.
350
</li><li><a href=\"/cgi-bin/cduce?example=seqtypes\">Sequence types.</a> 
351
Types for sequences.
352
</li><li><a href=\"/cgi-bin/cduce?example=integers\">The factorial function.</a> 
353
What about computing 10000! ?
354
</li><li><a href=\"/cgi-bin/cduce?example=sumtype\">Sum types.</a> 
355
How to simulate ML sum types.
356
</li><li><a href=\"/cgi-bin/cduce?example=ovfun\">Overloaded functions.</a> 
357
This examples demonstrates the use of overloaded functions.
358
</li><li><a href=\"/cgi-bin/cduce?example=note\">Footnotes.</a> 
359
 This example shows how to bind an XML element with surrounding text.
360
</li><li><a href=\"/cgi-bin/cduce?example=biblio\">Bibliography.</a> 
361
The good old XML bibliography example.
362
</li><li><a href=\"/cgi-bin/cduce?example=projection\">Projection.</a> 
363
Syntactic sugar for projection.
364
365
</li><li><a href=\"/cgi-bin/cduce?example=xtransform\">Tree transformations.</a> 
How to perform XSLT-like transformations.
366
</li></ul>"