Last active
August 29, 2015 14:11
-
-
Save KGZM/82e440d5284fc20942f0 to your computer and use it in GitHub Desktop.
Simple Comparison Between Haskell and OCaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{- rps.hs Simple Rock Paper Scissors written in Haskell | |
- for translation to Ocaml as a learning exercise. | |
-} | |
data Move = Rock | Paper | Scissors deriving (Show, Eq) | |
data Player = Player String deriving (Show, Eq) | |
data Outcome = Winner Player | Tie deriving (Show, Eq) | |
name :: Player -> String | |
name (Player s) = s | |
beats :: Move -> Move -> Bool | |
beats Rock Scissors = True | |
beats Scissors Paper = True | |
beats Paper Rock = True | |
beats _ _ = False | |
victor :: (Player, Move) -> (Player, Move) -> Outcome | |
victor (p1, m1) (p2, m2) | |
| m1 `beats` m2 = Winner p1 | |
| m2 `beats` m1 = Winner p2 | |
| otherwise = Tie | |
play :: Player -> Move -> Player -> Move -> String | |
play p1 m1 p2 m2 = | |
case victor (p1, m1) (p2, m2) of | |
Tie -> (name p1) ++ " and " ++ (name p2) ++ " tie with " ++ (show m1) ++ "." | |
Winner w -> | |
let (wp, wm, lp,lm) = | |
if w == p1 | |
then (p1, m1, p2, m2) | |
else (p2, m2, p1, m1) | |
in (name wp) ++ "'s " ++ (show wm) ++ " defeats " ++ (name lp) ++ "'s " ++ (show lm) ++ "." | |
jimmy = Player "Jimmy" | |
jack = Player "Jack" | |
moves = [Rock, Paper, Scissors] | |
main = do | |
let season = do m1s <- moves | |
m2s <- moves | |
return $ play jimmy m1s jack m2s | |
mapM_ putStrLn season |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(* rps.ml : Translation of Rock Paper Scissors from | |
* Haskell to Ocaml as a learning exercise. | |
*) | |
type move = Rock | Paper | Scissors | |
type player = Player of string | |
type outcome = Winner of player | Tie | |
let name (Player s) = s | |
let moveName m = match m with | |
| Rock -> "rock" | |
| Paper -> "paper" | |
| Scissors -> "scissors" | |
let beats m1 m2 = match m1, m2 with | |
| Rock, Scissors -> true | |
| Scissors, Paper -> true | |
| Paper, Rock -> true | |
| _, _ -> false | |
let victor (p1, m1) (p2, m2) = match () with | |
| () when beats m1 m2 -> Winner p1 | |
| () when beats m2 m1 -> Winner p2 | |
| _ -> Tie | |
let play p1 m1 p2 m2 = | |
let winstring = Printf.sprintf "%s's %s defeats %s's %s." | |
and tiestring = Printf.sprintf "%s and %s tie with %s." | |
in | |
match victor (p1, m1) (p2, m2) with | |
| Tie -> tiestring (name p1) (name p2) (moveName m1) | |
| Winner w -> | |
let wp, wm, lp, lm = | |
if w = p1 | |
then p1, m1, p2, m2 | |
else p2, m2, p1, m1 | |
in winstring (name wp) (moveName wm) (name lp) (moveName lm) | |
let jimmy = Player "Jimmy" | |
let jack = Player "Jack" | |
let moves = [Rock; Paper; Scissors] | |
let main () = | |
let concatMap f l = List.fold_right (fun v a -> (f v) @ a) l [] | |
and (|>) v f = f v in | |
let season = moves |> concatMap (fun m1 -> | |
moves |> List.map (fun m2 -> play jimmy m1 jack m2) | |
) | |
in List.iter print_endline season | |
let _ = main () |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# rps.coffee : CoffeeScript version of Rock Paper Scissors | |
# for comparison with Haskell and OCaml versions. | |
move = { | |
rock: "scissors" | |
scissors: "paper" | |
paper: "rock" | |
} | |
player = (name) -> {name} | |
outcome = (winner) -> { | |
type: if winner then "winner" else "tie" | |
winner: winner | |
} | |
beats = (m1, m2) -> move[m1] == m2 | |
victor = (p1, m1, p2, m2) -> | |
switch | |
when beats m1, m2 then outcome(p1) | |
when beats m2, m1 then outcome(p2) | |
else outcome() #This is our tie, not very snazzy. | |
play = (p1, m1, p2, m2) -> | |
result = victor p1, m1, p2, m2 | |
if not result.winner | |
"#{p1.name} and #{p2.name} tie with #{m1}." | |
else | |
[wp, wm, lp, lm] = | |
if result.winner is p1 | |
[p1, m1, p2, m2] | |
else | |
[p2, m2, p1, m1] | |
"#{wp.name}'s #{wm} defeats #{lp.name}'s #{lm}." | |
jimmy = player "jimmy" | |
jack = player "jack" | |
moves = ["rock", "paper", "scissors"] | |
moves.reduce((acc, m1) -> | |
acc.concat moves.map (m2) -> | |
play jimmy, m1, jack, m2 | |
,[]).forEach((s) -> console.log s) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment