Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add better burgers chapter #21

Merged
merged 5 commits into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/.vitepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export default defineConfig({
{ text: 'Order Confirmation', link: '/order-confirmation/' },
{ text: 'Styling with CSS', link: '/styling-with-css/' },
{ text: 'Better Sandwiches', link: '/better-sandwiches/' },
{ text: 'Better Burgers', link: '/better-burgers/' },
]
}
],
Expand Down
389 changes: 389 additions & 0 deletions docs/better-burgers/Item.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,389 @@
module ItemV1 = {
// #region starting-item-t
type sandwich =
| Portabello
| Ham
| Unicorn
| Turducken;

type t =
| Sandwich(sandwich)
| Burger
| Hotdog;
// #endregion starting-item-t
};

module ItemV2 = {
type sandwich =
| Portabello
| Ham
| Unicorn
| Turducken;

// #region add-burger-type
type burger = {
lettuce: bool,
onions: int,
cheese: int,
};

type t =
| Sandwich(sandwich)
| Burger(burger)
| Hotdog;
// #endregion add-burger-type

// #region to-emoji
let toEmoji =
fun
| Hotdog => {js|🌭|js}
| Sandwich(sandwich) =>
Printf.sprintf(
{js|🥪(%s)|js},
switch (sandwich) {
| Portabello => {js|🍄|js}
| Ham => {js|🐷|js}
| Unicorn => {js|🦄|js}
| Turducken => {js|🦃🦆🐓|js}
},
)
| Burger(burger) =>
Printf.sprintf(
{js|🍔{%s}|js},
[|
burger.lettuce ? {js|🥬|js} : "",
{js|🧅×|js} ++ string_of_int(burger.onions),
{js|🧀×|js} ++ string_of_int(burger.cheese),
|]
|> Js.Array.filter(str => str != "")
|> Js.Array.joinWith(", "),
);
// #endregion to-emoji

let toEmojiBurgerDestructure =
fun
| Hotdog
| Sandwich(_) => "fake"
// #region destructure-burger
| Burger(burger) => {
let {lettuce, onions, cheese} = burger;
Printf.sprintf(
{js|🍔{%s}|js},
[|
lettuce ? {js|🥬|js} : "",
{js|🧅×|js} ++ string_of_int(onions),
{js|🧀×|js} ++ string_of_int(cheese),
|]
|> Js.Array.filter(str => str != "")
|> Js.Array.joinWith(", "),
);
};
// #endregion destructure-burger

let toEmojiBurgerDestructureBranch =
fun
| Hotdog
| Sandwich(_) => "fake"
// #region destructure-burger-branch
| Burger({lettuce, onions, cheese}) =>
Printf.sprintf(
{js|🍔{%s}|js},
[|
lettuce ? {js|🥬|js} : "",
{js|🧅×|js} ++ string_of_int(onions),
{js|🧀×|js} ++ string_of_int(cheese),
|]
|> Js.Array.filter(str => str != "")
|> Js.Array.joinWith(", "),
);
// #endregion destructure-burger-branch

let toEmojiBurgerMultiple =
fun
| Hotdog
| Sandwich(_) => "fake"
// #region multiple
| Burger({lettuce, onions, cheese}) => {
let multiple = (emoji, count) =>
Printf.sprintf({js|%s×%d|js}, emoji, count);

Printf.sprintf(
{js|🍔{%s}|js},
[|
lettuce ? {js|🥬|js} : "",
multiple({js|🧅|js}, onions),
multiple({js|🧀|js}, cheese),
|]
|> Js.Array.filter(str => str != "")
|> Js.Array.joinWith(", "),
);
};
// #endregion multiple
};

module ItemV3 = {
// #region burger-submodule
module Burger = {
type t = {
lettuce: bool,
onions: int,
cheese: int,
};

let toEmoji = ({lettuce, onions, cheese}) => {
let multiple = (emoji, count) =>
Printf.sprintf({js|%s×%d|js}, emoji, count);

Printf.sprintf(
{js|🍔{%s}|js},
[|
lettuce ? {js|🥬|js} : "",
multiple({js|🧅|js}, onions),
multiple({js|🧀|js}, cheese),
|]
|> Js.Array.filter(str => str != "")
|> Js.Array.joinWith(", "),
);
};

let toPrice = _burger => 15.;
};
// #endregion burger-submodule

type sandwich =
| Portabello
| Ham
| Unicorn
| Turducken;

// #region t-and-functions
type t =
| Sandwich(sandwich)
| Burger(Burger.t)
| Hotdog;

let toEmoji =
fun
| Hotdog => {js|🌭|js}
| Burger(burger) => Burger.toEmoji(burger)
| Sandwich(sandwich) =>
Printf.sprintf(
{js|🥪(%s)|js},
switch (sandwich) {
| Portabello => {js|🍄|js}
| Ham => {js|🐷|js}
| Unicorn => {js|🦄|js}
| Turducken => {js|🦃🦆🐓|js}
},
);

let toPrice = t => {
let day = Js.Date.make() |> Js.Date.getDay |> int_of_float;

switch (t) {
| Sandwich(Portabello | Ham) => 10.
| Sandwich(Unicorn) => 80.
| Sandwich(Turducken) when day == 2 => 10.
| Sandwich(Turducken) => 20.
| Burger(burger) => Burger.toPrice(burger)
| Hotdog => 5.
};
};
// #endregion t-and-functions

module BurgerFunctions = {
type t = {
lettuce: bool,
onions: int,
cheese: int,
};

// #region record-wildcard
let toPrice = ({onions, cheese, _}) =>
15. // base cost
+. float_of_int(onions)
*. 0.2
+. float_of_int(cheese)
*. 0.1;
// #endregion record-wildcard

toPrice({lettuce: false, onions: 0, cheese: 0}) |> ignore;

// #region record-lettuce-wildcard
let toPrice = ({onions, cheese, lettuce: _}) =>
15. // base cost
+. float_of_int(onions)
*. 0.2
+. float_of_int(cheese)
*. 0.1;
// #endregion record-lettuce-wildcard

// #region ternary
let toEmoji = ({lettuce, onions, cheese}) => {
let multiple = (emoji, count) =>
Printf.sprintf({js|%s×%d|js}, emoji, count);

!lettuce && onions == 0 && cheese == 0
? {js|🍔|js}
: Printf.sprintf(
{js|🍔{%s}|js},
[|
lettuce ? {js|🥬|js} : "",
multiple({js|🧅|js}, onions),
multiple({js|🧀|js}, cheese),
|]
|> Js.Array.filter(str => str != "")
|> Js.Array.joinWith(", "),
);
};
// #endregion ternary

toEmoji({lettuce: false, onions: 0, cheese: 0}) |> ignore;

// #region match-tuple
let toEmoji = ({lettuce, onions, cheese}) => {
let multiple = (emoji, count) =>
Printf.sprintf({js|%s×%d|js}, emoji, count);

switch (lettuce, onions, cheese) {
| (false, 0, 0) => {js|🍔|js}
| (lettuce, onions, cheese) =>
Printf.sprintf(
{js|🍔{%s}|js},
[|
lettuce ? {js|🥬|js} : "",
multiple({js|🧅|js}, onions),
multiple({js|🧀|js}, cheese),
|]
|> Js.Array.filter(str => str != "")
|> Js.Array.joinWith(", "),
)
};
};
// #endregion match-tuple

toEmoji({lettuce: false, onions: 0, cheese: 0}) |> ignore;

// #region match-record
let toEmoji = t => {
let multiple = (emoji, count) =>
Printf.sprintf({js|%s×%d|js}, emoji, count);

switch (t) {
| {lettuce: false, onions: 0, cheese: 0} => {js|🍔|js}
| {lettuce, onions, cheese} =>
Printf.sprintf(
{js|🍔{%s}|js},
[|
lettuce ? {js|🥬|js} : "",
multiple({js|🧅|js}, onions),
multiple({js|🧀|js}, cheese),
|]
|> Js.Array.filter(str => str != "")
|> Js.Array.joinWith(", "),
)
};
};
// #endregion match-record
};
};

// #region sandwich-module
module Sandwich = {
type t =
| Portabello
| Ham
| Unicorn
| Turducken;

let toPrice = t => {
let day = Js.Date.make() |> Js.Date.getDay |> int_of_float;

switch (t) {
| Portabello
| Ham => 10.
| Unicorn => 80.
| Turducken when day == 2 => 10.
| Turducken => 20.
};
};

let toEmoji = t =>
Printf.sprintf(
{js|🥪(%s)|js},
switch (t) {
| Portabello => {js|🍄|js}
| Ham => {js|🐷|js}
| Unicorn => {js|🦄|js}
| Turducken => {js|🦃🦆🐓|js}
},
);
};
// #endregion sandwich-module

module BurgerTomatoBacon = {
// #region to-price-tomato-bacon
type t = {
lettuce: bool,
onions: int,
cheese: int,
tomatoes: bool,
bacon: int,
};

let toPrice = ({onions, cheese, tomatoes, bacon, lettuce: _}) =>
15. // base cost
+. float_of_int(onions)
*. 0.2
+. float_of_int(cheese)
*. 0.1
+. (tomatoes ? 0.05 : 0.0)
+. float_of_int(bacon)
*. 0.5;
// #endregion to-price-tomato-bacon

toPrice({lettuce: false, onions: 0, cheese: 0, tomatoes: false, bacon: 0})
|> ignore;

// #region to-price-topping-cost
let toPrice = ({onions, cheese, tomatoes, bacon, lettuce: _}) => {
let toppingCost = (quantity, cost) => float_of_int(quantity) *. cost;

15. // base cost
+. toppingCost(onions, 0.2)
+. toppingCost(cheese, 0.1)
+. (tomatoes ? 0.05 : 0.0)
+. toppingCost(bacon, 0.5);
};
// #endregion to-price-topping-cost

// #region to-emoji-multiple
let multiple = (emoji, count) =>
switch (count) {
| 0 => ""
| 1 => emoji
| count => Printf.sprintf({js|%s×%d|js}, emoji, count)
};
// #endregion to-emoji-multiple

multiple("", 0) |> ignore;

// #region to-emoji-multiple-fun
let multiple = emoji =>
fun
| 0 => ""
| 1 => emoji
| count => Printf.sprintf({js|%s×%d|js}, emoji, count);
// #endregion to-emoji-multiple-fun

multiple("", 0) |> ignore;

// #region to-emoji-multiple-fun-annotated
let multiple: (string, int) => string =
emoji =>
fun
| 0 => ""
| 1 => emoji
| count => Printf.sprintf({js|%s×%d|js}, emoji, count);
// #endregion to-emoji-multiple-fun-annotated
};
Loading