Thursday, August 18, 2011

Studying F# : Accumulator, pipe and composition

F#'s collection classes have some accumulator methods.
method namedescription
foldthe base accumulator method to accumulate a collection
fold2the variation of fold method to accumulate two collections
scanthe variation of fold method to return not only last result and but also intermediate results
reducethe special usage of fold method if both accumulator and elements are in same type

And collection classes have opposite accumulator methods - foldBack, foldBack2, scanBack and reduceBack. These methods are "reversed" - not only the order to scan collection but also the order of arguments for collection and initial accumulator.

I wrote a sample code using accumulator, pipe(|>) and composition(<<). This sample is of FizzBuzz on MapReduce.
Microsoft (R) F# 2.0 Interactive build 2.0.0.0
Copyright (c) Microsoft Corporation. All Rights Reserved.

For help type #help;;

> let fizzBuzzMapper data =
-     List.map ( fun elem -> (elem, (elem % 3 = 0), (elem % 5 = 0) ) ) data;;

val fizzBuzzMapper : int list -> (int * bool * bool) list

> [1..40] |> fizzBuzzMapper;;
val it : (int * bool * bool) list =
  [(1, false, false); (2, false, false); (3, true, false); (4, false, false);
   (5, false, true); (6, true, false); (7, false, false); (8, false, false);
   (9, true, false); (10, false, true); (11, false, false); (12, true, false);
   (13, false, false); (14, false, false); (15, true, true);
   (16, false, false); (17, false, false); (18, true, false);
   (19, false, false); (20, false, true); (21, true, false);
   (22, false, false); (23, false, false); (24, true, false);
   (25, false, true); (26, false, false); (27, true, false);
   (28, false, false); (29, false, false); (30, true, true);
   (31, false, false); (32, false, false); (33, true, false);
   (34, false, false); (35, false, true); (36, true, false);
   (37, false, false); (38, false, false); (39, true, false);
   (40, false, true)]
> let fizzBuzzReducer interims =
-     List.foldBack (fun (elem, m3, m5) acc ->
-         match (m3, m5) with
-         | (true, true) -> "FizzBuzz" :: acc
-         | (true, false) -> "Fizz" :: acc
-         | (false, true) -> "Buzz" :: acc
-         | _ -> elem.ToString() :: acc ) interims [];;

val fizzBuzzReducer : ('a * bool * bool) list -> string list

> [1..40] |> fizzBuzzMapper |> fizzBuzzReducer;;
val it : string list =
  ["1"; "2"; "Fizz"; "4"; "Buzz"; "Fizz"; "7"; "8"; "Fizz"; "Buzz"; "11";
   "Fizz"; "13"; "14"; "FizzBuzz"; "16"; "17"; "Fizz"; "19"; "Buzz"; "Fizz";
   "22"; "23"; "Fizz"; "Buzz"; "26"; "Fizz"; "28"; "29"; "FizzBuzz"; "31";
   "32"; "Fizz"; "34"; "Buzz"; "Fizz"; "37"; "38"; "Fizz"; "Buzz"]
> [1..40] |> (fizzBuzzReducer << fizzBuzzMapper) |> List.iter (fun elem -> System.Console.WriteLine(elem));;
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz
Fizz
22
23
Fizz
Buzz
26
Fizz
28
29
FizzBuzz
31
32
Fizz
34
Buzz
Fizz
37
38
Fizz
Buzz
val it : unit = ()

No comments:

Post a Comment