let examples = [ "functions"," (* Simple functions can be defined this way: *) let fun f1 (x : Int) : Int = x + 3;; f1 5;; (* With several arguments: *) let fun f2 (x : Int, y : Int) : Int = x + y;; f2 (10,20);; (* You may directly deconstruct the arguments: *) type A = String;; let fun f3 (txt : A) : String = url @ \"=>\" @ txt;; f3 \"CDuce homepage\";; (* In general, if you want to specify several arrow types, or use several pattern matching branches, you have the general form: *) let fun f4 (A -> String; ['0'--'9'+] -> Int) | x & A -> f3 x | x -> int_of x;; f4 \"123\";; ";"mutrec"," (* All the types submitted at once are mutually recursive *) type T = S;; type S = [ (Char | T)* ];; let x : S = [ 'abc' ['def'] 'ghi' ];; (* Consecutive function definitions (without any other toplevel phrase in the middle) are grouped together *) let fun f (x : Int) : Int = g x;; let fun g (x : Int) : Int = 3;; let a = 2;; let fun h (x : Int) : Int = f x;; (* f and g are mutually recursive, but they cannot use h *) ";"seq"," (* Sequence are just defined with pairs and the atom `nil; the following notation are equivalent: *) let l1 = (1,2,3,`nil);; let l2 = (1,(2,(3,`nil)));; let l3 = [ 1 2 3 ];; (* The [...] notation allow to specify a tail after a semi-colon : *) let l4 = (10,20,l1);; let l5 = [ 10 20 ; l1 ];; (* Concatenation @ *) let l6 = [ 1 2 3 ] @ [ 4 5 6 ];; (* Inside [...], it is possible to escape a subsequence with a ! *) let l7 = [ 1 2 !l6 !l1 5 ];; ";"seqtypes"," (* Sequence types are defined with regular expression over types *) type IntList = [ Int* ];; type IntStringList = [ (Int String)* ];; type IntNonEmptyList = [ Int+ ];; let l : IntList = [ 1 2 3 ];; ";"integers"," (* Yes, CDuce can handle large integers! *) let fun facto (Int -> Int) | 0 | 1 -> 1 | n -> n * (facto (n - 1)) in facto 300;; (* The tail-recursive way *) let fun facto ((Int,Int) -> Int) | (x, 0 | 1) -> x | (x, n) -> facto (x * n, n - 1) in facto (1,10000);; ";"sumtype"," type Expr = (`add, Expr, Expr) | (`mul, Expr, Expr) | (`sub, Expr, Expr) | (`div, Expr, Expr) | Int;; let fun eval ( Expr -> Int ) | (`add,x,y) -> eval x + eval y | (`mul,x,y) -> eval x * eval y | (`sub,x,y) -> eval x - eval y | (`div,x,y) -> (eval x) div (eval y) | n -> n in eval (`add, 10, (`mul, 20, 5));; ";"ovfun"," type Person = FPerson | MPerson;; type FPerson = [ Name Children (Tel | Email)?];; type MPerson = [ Name Children (Tel | Email)?];; type Children = [Person*];; type Name = [ PCDATA ];; type Tel = ['0'--'9'+ '-' '0'--'9'+];; type Email = [PCDATA '@' PCDATA];; type Man = [ Sons Daughters ];; type Woman = [ Sons Daughters ];; type Sons = [ Man* ];; type Daughters = [ Woman* ];; let fun sort (MPerson -> Man ; FPerson -> Woman) [ n [(mc::MPerson | fc::FPerson)*]; _] -> let tag = match g with \"F\" -> `woman | \"M\" -> `man in let s = map mc with x -> sort x in let d = map fc with x -> sort x in <(tag) name=n>[ s d ] ;; let base : Person = [ \"Claude\" [ [ \"Véronique\" [ [ \"Ilaria\" [] ] ] \"314-1592654\" ] ] \"271-828182\" ] ;; sort base;; ";"note"," type Doc = Text;; type Text = [ (Char | (Letter+ ' '* Note))* ];; type Letter = 'a'--'z' | 'A'--'Z';; type Note = [ PCDATA ];; type Flow = [ (Char | [ PCDATA ])* ];; type Notes = [ [ PCDATA ]* ];; type Result = [ Flow Notes ];; let fun format (s : Doc) : Result = let (body,notes) = text (s,1) in [ body notes ];; let fun text ( (Text,Int) -> (Flow,Notes) ) | ([ pre::Char*? (word::Letter+ ' '* n); rem ], count) -> let (body,notes) = text (rem, count + 1) in (pre @ [word] @ body, [n] @ notes) | (body,_) -> (body, []);; let src : Doc = [ 'CDuce ' \"Frisch, Castagna, Benzaken\" ' is an XML ' \"a W3C standard\" '-friendly programming language.' ];; format src;; ";"biblio"," 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 ];; (* Simplified HTML *) type Html = <html>[ <head>[ <title>[ PCDATA ] ] <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);; let fun do_paper (Paper -> <li>Mix) <paper>[ x::_* <title>t <conference>c <file>f ] -> <li>[ <a href=f>t !(do_authors x) '; in ' <em>c '.' ];; 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 ];; 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\" ] ];; do_biblio bib;; ";"projection"," (* The projection e/t is translated to: transform e with [ (x::t|_)* ] -> x *) 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 ];; 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\" ] ];; let titles = [bib]/<paper>_/<title>_;; let authors = [bib]/<paper>_/<author>_;; let titles_concat = [bib]/<paper>_/<title>_/Char;; "; ];; let present = "<ul ><li ><a href=\"/cgi-bin/cduce?example=functions\" >Functions.</a > Several syntaxes to define functions. </li ><li ><a href=\"/cgi-bin/cduce?example=mutrec\" >Mutual recursion.</a > Mutual toplevel definition for types and functions. </li ><li ><a href=\"/cgi-bin/cduce?example=seq\" >Sequence literals.</a > How to write sequences. </li ><li ><a href=\"/cgi-bin/cduce?example=seqtypes\" >Sequence types.</a > Types for sequences. </li ><li ><a href=\"/cgi-bin/cduce?example=integers\" >The factorial function.</a > What about computing 10000! ? </li ><li ><a href=\"/cgi-bin/cduce?example=sumtype\" >Sum types.</a > How to simulate ML sum types. </li ><li ><a href=\"/cgi-bin/cduce?example=ovfun\" >Overloaded functions.</a > This examples demonstrates the use of overloaded functions. </li ><li ><a href=\"/cgi-bin/cduce?example=note\" >Footnotes.</a > This example shows how to bind an XML element with surrounding text. </li ><li ><a href=\"/cgi-bin/cduce?example=biblio\" >Bibliography.</a > The good old XML bibliography example. </li ><li ><a href=\"/cgi-bin/cduce?example=projection\" >Projection.</a > Syntactic sugar for projection. </li ></ul >";;