Voting

Category

real language

Bookmarking

Del.icio.us Digg Diigo DZone Earthlink Google Kick.ie
Windows Live LookLater Ma.gnolia Reddit Rojo StumbleUpon Technorati

Language F#

(Using list comprehension)

Date:02/01/09
Author:Jörn Rönnow
URL:n/a
Comments:3
Info:http://research.microsoft.com/fsharp
Score: (3.02 in 111 votes)
#light

let bottleStr bottles = 
    match bottles with
    | 0 -> "no more bottles"
    | 1 -> "1 bottle"
    | _ -> bottles.ToString() + " bottles"

let verse n =
    match n with
    | 0 -> "No more bottles of beer on the wall, no more bottles of beer.\n" +
           "Go to the store and buy some more, 99 bottles of beer on the wall.\n"
    | _ -> bottleStr n + " of beer on the wall, " + bottleStr n + " of beer.\n" +
           "Take one down and pass it around, " + bottleStr (n-1) + 
           " of beer on the wall.\n"

List.iter (printfn "%s") [for v in [99..-1..0] -> verse v]

Download Source | Write Comment

Alternative Versions

VersionAuthorDateCommentsRate
Tail Recursion CallSimon Kang06/22/090
Cleaner stillDon Syme12/07/060
Recursive implementationAlec Zorab07/04/090
lists and lambda'sKyle Eppley05/04/100

Comments

>>  Jörn Rönnow said on 03/11/09 16:24:59

Jörn Rönnow Those who prefer not to generate a list of the verses before printing them, could iterate over a list of integers instead, replacing the last line with

List.iter (fun v -> printfn "%s" (verse v)) [99..-1..0]

Using function composition, which is a neat functional language feature, verse and printfn can be composed into a new function by (verse >> printfn "%s";), so we can write

List.iter (fun v -> (verse >> printfn "%s";) v) [99..-1..0]

Function pipelining, the |> operator in F#, is yet another neat feature of functional languages, which lets you chain functions together, passing the result of one function on as the argument of the next. It looks like this:

[99..-1..0] |> List.iter (fun v -> v |> verse |> printfn "%s";)

>>  Jörn Rönnow said on 03/11/09 16:29:14

Jörn Rönnow OOOPS! The above comment became a bit cryptic, since some of my paranthesis expressions turned into smilies. This is a new attempt:

Those who prefer not to generate a list of the verses before printing them, could iterate over a list of integers instead, replacing the last line with

List.iter (fun v -> printfn "%s" (verse v)) [99..-1..0]

Using function composition, which is a neat functional language feature, verse and printfn can be composed into a new function by ( verse >> printfn "%s" ), so we can write

List.iter (fun v -> ( verse >> printfn "%s" ) v) [99..-1..0]

Function pipelining, the |> operator in F#, is yet another neat feature of functional languages, which lets you chain functions together, passing the result of one function on as the argument of the next. It looks like this:

[99..-1..0] |> List.iter ( fun v -> v |> verse |> printfn "%s" )

>>  kyle eppley said on 05/03/10 17:52:38

kyle eppley Curious... I posted an almost identical version last july and never herd or seen it...

module BeerProg /// required for compile error in fsi

let a = " of beer " /// strings used in order of apperance
let b = "on the wall"
let c = "take one down pass it around"
let z = "No more bottles of beer on the wall, no more bottles of beer.\n" +
"Go to the store and buy some more, 99 bottles of beer on the wall.\n"

let bs n = /// correct notation of bottles verse n
match n with /// use match to correct the tense
| 0 -> "no more bottles" /// 0
| 1 -> "1 bottle" /// 1
| _ -> n.ToString() + " bottles" //// 99-2

let beer n = /// print beer each line then last verse
List.iter (fun i -> /// iterate list, printf for each item in the list following it
printfn "%s%s%s, %s%s\n%s, %s%s%s\n" (bs i) a b (bs i) a c (bs (i-1)) a b)
[n..(-1)..1] /// create list 99 down to 1
printfn "%s" z /// last verse since it is unique

beer 99;;

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!

Name:

eMail:

URL:

Security Code:
  
Comment: