FizzBuzz in Haskell by Embedding a DSL
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

FizzBuzz in Haskell by Embedding a DSL

on

  • 328 views

Fun in the Afternoon @ Facebook (March 2014)

Fun in the Afternoon @ Facebook (March 2014)

Statistics

Views

Total Views
328
Views on SlideShare
328
Embed Views
0

Actions

Likes
0
Downloads
0
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

FizzBuzz in Haskell by Embedding a DSL Presentation Transcript

  • 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. 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. 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. 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. 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. (+<+) :: 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. 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. [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. 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. 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. 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. 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. 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. 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. 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. 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. 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. The End Questions?