Skip to content

Commit c5a0721

Browse files
authored
Merge pull request #3787 from luishendrix92/main
#21 - OCaml
2 parents e12e263 + 47914bc commit c5a0721

File tree

1 file changed

+178
-0
lines changed

1 file changed

+178
-0
lines changed
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
open Printf
2+
3+
(****************************************************************************)
4+
(* *)
5+
(* Callbacks (HoF) *)
6+
(* *)
7+
(* As a functional programming language, OCaml is perfectly capable of *)
8+
(* treating functions as first-class citizens; meaning, we can store them *)
9+
(* inside variables, accept them as parameters, return them from other *)
10+
(* functions, and more! *)
11+
(* *)
12+
(* In programming, a {b callback} is a function that is passed as an *)
13+
(* argument to a function, which will be later called (with or without *)
14+
(* arguments) once a certain task is completed synchronously or *)
15+
(* asynchronously. The term was popularized by the inception of NodeJS's *)
16+
(* single-threaded concurrent programming but it goes beyond just that... *)
17+
(* both in history and use cases. A callback can be just a function that *)
18+
(* represent a strategy, or can be a set of instructions to run at a *)
19+
(* certain point in time; it can be virtually any type of function, *)
20+
(* really; as long as it's passed as an argument to another function. *)
21+
(* *)
22+
(****************************************************************************)
23+
24+
let with_named_parameters ~callback name =
25+
let greeting = sprintf "Hello, %s! How are you today?" name in
26+
printf "HoF 'with_named_parameters' will run callback with [%s]...\n" name;
27+
callback greeting;
28+
print_endline
29+
"Higher-Order Function 'with_named_parameters' finished execution!"
30+
;;
31+
32+
let _ =
33+
(* Why have [callback] as a named parameter?
34+
It's idiomatic in the OCaml world... *)
35+
with_named_parameters
36+
~callback:(fun greeting -> printf "Greeting received: %s\n" greeting)
37+
"Luis";
38+
print_newline ()
39+
;;
40+
41+
(**************************************************************************)
42+
(* *)
43+
(* Dificultad Extra (opcional) *)
44+
(* *)
45+
(* Crea un simulador de pedidos de un restaurante utilizando callbacks. *)
46+
(* Estará formado por una función que procesa pedidos. *)
47+
(* Debe aceptar el nombre del plato, una callback de confirmación, una *)
48+
(* de listo, y otra de entrega. *)
49+
(* *)
50+
(* - Debe imprimir una confirmación cuando empiece el procesamiento. *)
51+
(* - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre *)
52+
(* procesos. *)
53+
(* - Debe invocar a cada callback siguiendo un orden de procesado. *)
54+
(* - Debe notificar que el plato está listo o ha sido entregado. *)
55+
(* *)
56+
(**************************************************************************)
57+
58+
let wait_between_1_and_10_seconds () = Thread.delay (Random.float 9.0 +. 1.0)
59+
60+
module Restaurant : sig
61+
val show_menu : unit -> unit
62+
63+
val place_order
64+
: on_confirmed:(unit -> unit)
65+
-> on_ready:(unit -> unit)
66+
-> on_delivered:(string -> unit)
67+
-> int
68+
-> unit
69+
end = struct
70+
Random.self_init ()
71+
72+
type dish =
73+
| HotDog
74+
| Cheeseburger
75+
| CaesarSalad
76+
| Chicken
77+
| Shortcake
78+
| Ramen
79+
[@@deriving show]
80+
81+
let dish_of_int = function
82+
| 1 -> HotDog
83+
| 2 -> Cheeseburger
84+
| 3 -> CaesarSalad
85+
| 4 -> Chicken
86+
| 5 -> Shortcake
87+
| 6 -> Ramen
88+
| _ -> raise (Invalid_argument "Dish number not in the menu")
89+
;;
90+
91+
let dish_to_emoji = function
92+
| HotDog -> "🌭"
93+
| Cheeseburger -> "🍔"
94+
| CaesarSalad -> "🥗"
95+
| Chicken -> "🍗"
96+
| Shortcake -> "🍰"
97+
| Ramen -> "🍜"
98+
;;
99+
100+
let show_menu () =
101+
print_endline "#1 <- Hot dog";
102+
print_endline "#2 <- Cheeseburger";
103+
print_endline "#3 <- Caesar salad";
104+
print_endline "#4 <- Chicken wings";
105+
print_endline "#5 <- Strawberry shortcake";
106+
print_endline "#6 <- Ramen bowl"
107+
;;
108+
109+
let process_order ~on_confirmed ~on_ready ~on_delivered dish =
110+
wait_between_1_and_10_seconds ();
111+
print_endline "Order was confirmed, invoking confirmation callback...";
112+
on_confirmed ();
113+
wait_between_1_and_10_seconds ();
114+
print_endline "Order is ready, invoking readiness callback...";
115+
on_ready ();
116+
wait_between_1_and_10_seconds ();
117+
print_endline "Order being delived to table, invoking delivery callback...";
118+
on_delivered (dish_to_emoji dish)
119+
;;
120+
121+
let place_order ~on_confirmed ~on_ready ~on_delivered dish_number =
122+
let dish = dish_of_int dish_number in
123+
let order_thread =
124+
Thread.create (process_order ~on_confirmed ~on_ready ~on_delivered) dish
125+
in
126+
printf
127+
"Restaurant cashier says: Order [%s] has been placed!\n"
128+
(show_dish dish);
129+
print_endline "---------------------------------------------------";
130+
Thread.join order_thread
131+
;;
132+
end
133+
134+
let _ =
135+
print_endline "Welcome to my restaurant! Here's the menu:";
136+
Restaurant.show_menu ();
137+
let dish_number =
138+
Moure.Io.prompt
139+
~err_msg:"Invalid number"
140+
~f:int_of_string
141+
"Choose a menu item between 1 and 6: "
142+
in
143+
match dish_number with
144+
| Ok dish_number ->
145+
Restaurant.place_order
146+
~on_confirmed:(fun () ->
147+
print_endline "Customer says: Time to take a seat :)")
148+
~on_ready:(fun () ->
149+
print_endline "Customer says: Food's ready? I'll be waiting!")
150+
~on_delivered:(fun emoji ->
151+
printf "Customer says: Yum, time to eat my [%s]!\n" emoji)
152+
dish_number
153+
| Error msg -> print_endline msg
154+
;;
155+
156+
(* Output of [dune exec reto21]:
157+
158+
HoF 'with_named_parameters' will run callback with [Luis]...
159+
Greeting received: Hello, Luis! How are you today?
160+
Higher-Order Function 'with_named_parameters' finished execution!
161+
162+
Welcome to my restaurant! Here's the menu:
163+
#1 <- Hot dog
164+
#2 <- Cheeseburger
165+
#3 <- Caesar salad
166+
#4 <- Chicken wings
167+
#5 <- Strawberry shortcake
168+
#6 <- Ramen bowl
169+
Choose a menu item between 1 and 6: 2
170+
Restaurant cashier says: Order [Reto21.Restaurant.Cheeseburger] has been placed!
171+
---------------------------------------------------
172+
Order was confirmed, invoking confirmation callback...
173+
Customer says: Time to take a seat :)
174+
Order is ready, invoking readiness callback...
175+
Customer says: Food's ready? I'll be waiting!
176+
Order being delived to table, invoking delivery callback...
177+
Customer says: Yum, time to eat my [🍔]!
178+
*)

0 commit comments

Comments
 (0)