FizzBuzz in Haskell by Embedding a DSL
or: how to get a job (at Facebook?)
Maciej Piróg
UOxford
FUN@FB
March 2014
Players generally sit  in a circle. The player 
designated to go first says the number "1", 
and each player thenceforth c...
FizzBuzz ­­ a hard nut to crack for programmers
fizzbuzz n =
“fizzbuzz” if    n`mod`3==0
              && n`mod`5==0
“fizz...
FizzBuzz ­­ a hard nut to crack for programmers
fizzbuzz n =
“fizzbuzz” if    n`mod`3==0
              && n`mod`5==0
“fizz...
fizzbuzz n :: Int ­> String
fizzbuzz n =
  if n `mod` 3 == 0
    then "fizz" ++  if n `mod` 5 == 0
                      t...
(+<+) :: String ­> String ­> String
"" +<+ s = s
a  +<+ s = a
fizzbuzz :: Int ­> String
fizzbuzz n =
 (  (if n`mod`3==0 th...
data Cmd      = Print String | Skip | Halt 
type Program  = [Cmd]
interp :: Program ­> String
interp []             = ""
i...
[Skip, Halt, Print "fun"]
One­hole contexts
[Skip, Halt, ? , Print "fun"]
[Skip, Halt] ++ ? ++ [Print "fun"]
x   [Skip, Ha...
base, fizz, buzz :: Int ­> Cont
base  n       = x   → x ++ [Print (show n)]
fizz  n
 | n`mod`3==0 = x   [Print "fizz"] ++ ...
Spin the wheel
step :: Cmd ­> String ­> String
step Skip       t  = t
step Halt       t  = ""
step (Print s)  t  = s ++ t
...
Spin the wheel (2)
foldr step "" [Print "c", Halt, Skip]
=
foldr (.) id [step (Print "c"), step Halt,
              step S...
Spin the wheel (2)
foldr step "" [Print "c", Halt, Skip]
=
foldr (.) id [step (Print "c"), step Halt,
              step S...
Spin the wheel (2)
foldr step "" [Print "c", Halt, Skip]
=
foldr (.) id [step (Print "c"), step Halt,
              step S...
base, fizz, buzz :: Int ­> Cont
base  n       = x   → x ++ [Print (show n)]
fizz  n
 | n`mod`3==0 = x   [Print "fizz"] ++ ...
base, fizz, buzz :: Int ­> Cont
base  n       = x   → x . (show n ++)
fizz  n
 | n`mod`3==0 = x   ("fizz" ++) . → x . (con...
fizzbuzz :: Int ­> String
fizzbuzz n = (fizz . buzz) id (show n)
 where
  fizz  n
   | n`mod`3==0 = x   const ("fizz" ++ →...
fizzbuzz :: Int ­> String
fizzbuzz n =
  (test 3 "fizz" . test 5  "buzz") id (show n)
 where
  test d s x
   | n`mod`d==0 ...
The End
Questions?
Upcoming SlideShare
Loading in …5
×

FizzBuzz in Haskell by Embedding a DSL

955 views

Published on

Fun in the Afternoon @ Facebook (March 2014)

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
955
On SlideShare
0
From Embeds
0
Number of Embeds
30
Actions
Shares
0
Downloads
2
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

FizzBuzz in Haskell by Embedding a DSL

  1. 1. FizzBuzz in Haskell by Embedding a DSL or: how to get a job (at Facebook?) Maciej Piróg UOxford FUN@FB March 2014
  2. 2. Players generally sit  in a circle. The player  designated to go first says the number "1",  and each player thenceforth counts one number  in turn. However, any number divisible by  three is replaced by the word fizz and any  divisible by five by the word buzz. Numbers  divisible by both become fizzbuzz.                                   [Wikipedia] FizzBuzz ­­ a simple game for children
  3. 3. FizzBuzz ­­ a hard nut to crack for programmers fizzbuzz n = “fizzbuzz” if    n`mod`3==0               && n`mod`5==0 “fizz”     if n`mod`3==0  “buzz”     if n`mod`5==0 show n     otherwise
  4. 4. FizzBuzz ­­ a hard nut to crack for programmers fizzbuzz n = “fizzbuzz” if    n`mod`3==0               && n`mod`5==0 “fizz”     if n`mod`3==0  “buzz”     if n`mod`5==0 show n     otherwise What about FizzBuzzHissHowl problem for mod3, mod5, mod7, and mod11? We repeat e.g. mod3 test (modularity?)
  5. 5. fizzbuzz n :: Int ­> String fizzbuzz n =   if n `mod` 3 == 0     then "fizz" ++  if n `mod` 5 == 0                       then "buzz"                       else ""     else  if n `mod` 5 == 0                       then "buzz"                       else show n  Solution B
  6. 6. (+<+) :: String ­> String ­> String "" +<+ s = s a  +<+ s = a fizzbuzz :: Int ­> String fizzbuzz n =  (  (if n`mod`3==0 then "fizz" else "")  ++ (if n`mod`5==0 then "buzz" else "") )  +<+ show n  Solution C
  7. 7. data Cmd      = Print String | Skip | Halt  type Program  = [Cmd] interp :: Program ­> String interp []             = "" interp (Print s : xs) = s ++ interp xs interp (Skip    : xs) = interp xs interp (Halt    : xs) = ""  The Skip­Halt­Print  language
  8. 8. [Skip, Halt, Print "fun"] One­hole contexts [Skip, Halt, ? , Print "fun"] [Skip, Halt] ++ ? ++ [Print "fun"] x   [Skip, Halt] ++ → x ++ [Print "fun"] type Cont = Program ­> Program Higher-order abstract syntax
  9. 9. base, fizz, buzz :: Int ­> Cont base  n       = x   → x ++ [Print (show n)] fizz  n  | n`mod`3==0 = x   [Print "fizz"] ++ → x ++ [Halt]  | otherwise  = id buzz  n  | n`mod`5==0 = x   [Print "buzz"] ++ → x ++ [Halt]  | otherwise  = id fb :: Int ­> Program fb n = (base n . fizz n . buzz n) [Skip] fizzbuzz :: Int ­> String fizzbuzz n = interp (fb n)
  10. 10. Spin the wheel step :: Cmd ­> String ­> String step Skip       t  = t step Halt       t  = "" step (Print s)  t  = s ++ t interp = foldr step "" interp is a fold!
  11. 11. Spin the wheel (2) foldr step "" [Print "c", Halt, Skip] = foldr (.) id [step (Print "c"), step Halt,               step Skip]  "" Since foldr step "" p = foldr (.) id (fmap step p) ""
  12. 12. Spin the wheel (2) foldr step "" [Print "c", Halt, Skip] = foldr (.) id [step (Print "c"), step Halt,               step Skip]  "" = foldr (.) id [("c"++), const "", id] "" inlining
  13. 13. Spin the wheel (2) foldr step "" [Print "c", Halt, Skip] = foldr (.) id [step (Print "c"), step Halt,               step Skip]  "" = foldr (.) id [("c"++), const "", id] "" = (("c"++) . (const "") . id) "" more inlining
  14. 14. base, fizz, buzz :: Int ­> Cont base  n       = x   → x ++ [Print (show n)] fizz  n  | n`mod`3==0 = x   [Print "fizz"] ++ → x ++ [Halt]  | otherwise  = id buzz  n  | n`mod`5==0 = x   [Print "buzz"] ++ → x ++ [Halt]  | otherwise  = id fb :: Int ­> Program fb n = (base n . fizz n . buzz n) [Skip] fizzbuzz :: Int ­> String fizzbuzz n = interp (fb n)
  15. 15. base, fizz, buzz :: Int ­> Cont base  n       = x   → x . (show n ++) fizz  n  | n`mod`3==0 = x   ("fizz" ++) . → x . (const "")  | otherwise  = id buzz  n  | n`mod`5==0 = x   ("buzz" ++) . → x . (const "")  | otherwise  = id fizzbuzz :: Int ­> String fizzbuzz n = (base n . fizz n . buzz n) ""
  16. 16. fizzbuzz :: Int ­> String fizzbuzz n = (fizz . buzz) id (show n)  where   fizz  n    | n`mod`3==0 = x   const ("fizz" ++ → x "")    | otherwise  = id   buzz  n    | n`mod`5==0 = x   const ("buzz" ++ → x "")    | otherwise  = id
  17. 17. fizzbuzz :: Int ­> String fizzbuzz n =   (test 3 "fizz" . test 5  "buzz") id (show n)  where   test d s x    | n`mod`d==0 =  const  (s ++ x "")    | otherwise  =  x     test ::   Int­>String­>(String­>String)­>String­>String
  18. 18. The End Questions?

×