Language OCaml
(version with recursive variant type)
Date: | 11/18/05 |
Author: | Pierre Etchemaïté |
URL: | n/a |
Comments: | 1 |
Info: | http://www.ocaml.org/ |
Score: | (2.93 in 14 votes) |
(* We first build the datastructure of the whole song, then convert it to its text form. This demonstrates recursive variants, tuple and record types. *) type lyrics = | Strophe of strophe | Verse of lyrics * lyrics (* hemistichs *) | Bottle of int | Wall of lyrics | TakeOneDown | GoToTheStore | TheEnd and strophe = { verse1 : lyrics; verse2 : lyrics; remaining : lyrics } let build_lyrics n0 = let rec build_strophe n = if n > 0 then Strophe { verse1 = Verse (Wall (Bottle n), Bottle n); verse2 = Verse (TakeOneDown, Wall (Bottle (n-1))); remaining = build_strophe (n-1) } else Strophe { verse1 = Verse (Wall (Bottle n), Bottle n); verse2 = Verse (GoToTheStore, Wall (Bottle n0)); remaining = TheEnd } in build_strophe n0 let rec lyrics_to_string l = let strophe_to_string s = (lyrics_to_string s.verse1) ^ "\n" ^ (lyrics_to_string s.verse2) ^ "\n" in match l with | TheEnd -> "" | Strophe ({ remaining = TheEnd } as s) -> strophe_to_string s | Strophe ({ remaining = next } as s) -> (strophe_to_string s) ^ "\n" ^ (lyrics_to_string next) | Verse (hemistich1, hemistich2) -> String.capitalize ( (lyrics_to_string hemistich1) ^ ", " ^ (lyrics_to_string hemistich2) ^ "." ) | Bottle n -> (match n with | 0 -> "no more bottles" | 1 -> "1 bottle" | n -> (string_of_int n) ^ " bottles") ^ " of beer" | Wall l -> (lyrics_to_string l) ^ " on the wall" | TakeOneDown -> "take one down and pass it around" | GoToTheStore -> "go to the store and buy some more" let _ = print_string (lyrics_to_string (build_lyrics 99))
Download Source | Write Comment
Alternative Versions
Version | Author | Date | Comments | Rate |
---|---|---|---|---|
working with new versions, using printf | David Baelde | 11/08/05 | 0 | |
functional version | Anonymous | 04/20/05 | 0 | |
A little modification to the current one | Philippe Wang | 01/28/06 | 1 | |
historic version | Philipp Winterberg | 04/20/05 | 0 |
Download Source | Write Comment
Add Comment
Please provide a value for the fields Name,
Comment and Security Code.
This is a gravatar-friendly website.
E-mail addresses will never be shown.
Enter your e-mail address to use your gravatar.
Please don't post large portions of code here! Use the form to submit new examples or updates instead!
Comments
petchema said on 03/26/06 03:13:08
To take the defense of my variant, such style is not purely artificial; It's even common in compilers, code generators, etc. (See Abstract Syntax Trees http://en.wikipedia.org/wiki/Abstract_syntax_tree).
In this "99 bottles" case, while this variant is larger than others, it has its own merits: it allows to separate problems.
Want to implement variants of the song ? Modify the generator.
Want to output XML, HTML, Postscript ? Or output the song in german ? Modify the printer.
The AST type probably needs changes however
If you worry about performance... Well first, that version is still plenty fast.
However, lazy values could be used so that the AST is only computed as needed (and even probably partially garbage collected during output...). And printer could either do direct I/O to avoid keeping whole text in memory, or at least use Buffer to generate it efficiently. Exercice left to the reader, I wanted to keep the code easy to grasp...