Skip to content

Commit ca2c495

Browse files
skylee03peter-jerry-ye
authored andcommitted
Use plain functions for IntMap
1 parent 2d1108d commit ca2c495

File tree

2 files changed

+54
-28
lines changed

2 files changed

+54
-28
lines changed

course3/course_en.md

+27-14
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,19 @@ style: |
1818
<!--
1919
```moonbit
2020
let pi = 3.1415
21+
22+
fn put(map: @map.Map[Int, Int64], num: Int, result: Int64) -> @map.Map[Int, Int64] {
23+
map.insert(num, result)
24+
}
25+
26+
fn get(map: @map.Map[Int, Int64], num: Int) -> Option[Int64] {
27+
map.lookup(num)
28+
}
29+
30+
fn make() -> @map.Map[Int, Int64] {
31+
@map.empty()
32+
}
33+
2134
```
2235
-->
2336

@@ -594,9 +607,9 @@ A large number of duplicated subproblems was observed.
594607
- We need a data structure whose average access efficiency is independent of the data size, and it should have the following interfaces:
595608

596609
```moonbit no-check
597-
fn empty() -> IntMap // Create
598-
fn insert(self: IntMap, key: Int, value: Int64) -> IntMap // Store
599-
fn lookup(self: IntMap, key: Int) -> Option[Int64] // Retrieve
610+
fn make() -> IntMap // Create
611+
fn put(map: IntMap, num: Int, value: Int64) -> IntMap // Store
612+
fn get(map: IntMap, num: Int) -> Option[Int64] // Retrieve
600613
```
601614

602615
- There are many siutable data structures, e.g., `@map.Map[Int, Int64]`.
@@ -614,16 +627,16 @@ fn lookup(self: IntMap, key: Int) -> Option[Int64] // Retrieve
614627
```moonbit expr
615628
fn fib1(num: Int) -> Int64 {
616629
fn aux(num: Int, map: @map.Map[Int, Int64]) -> (Int64, @map.Map[Int, Int64]) {
617-
match map.lookup(num) {
630+
match get(map, num) {
618631
Some(result) => (result, map)
619632
None => {
620633
let (result_1, map_1) = aux(num - 1, map)
621634
let (result_2, map_2) = aux(num - 2, map_1)
622-
(result_1 + result_2, map_2.insert(num, result_1 + result_2))
635+
(result_1 + result_2, put(map_2, num, result_1 + result_2))
623636
}
624637
}
625638
}
626-
let map = @map.empty().insert(1, 1L).insert(2, 1L)
639+
let map = put(put(make(), 1, 1L), 2, 1L)
627640
aux(num, map).0
628641
}
629642
```
@@ -638,15 +651,15 @@ To simplify the code, MoonBit supports mutable variables.
638651
```moonbit expr
639652
fn fib1_mut(num: Int) -> Int64 {
640653
// Declare a mutable variable with let mut
641-
let mut map = @map.empty().insert(1, 1L).insert(2, 1L)
654+
let mut map = put(put(make(), 1, 1L), 2, 1L)
642655
fn aux(num: Int) -> Int64 {
643-
match map.lookup(num) {
656+
match get(map, num) {
644657
Some(result) => result
645658
None => {
646659
let result_1 = aux(num - 1)
647660
let result_2 = aux(num - 2)
648661
// Update the binding with <variable> = <expression>
649-
map = map.insert(num, result_1 + result_2)
662+
map = put(map, num, result_1 + result_2)
650663
result_1 + result_2
651664
}
652665
}
@@ -664,12 +677,12 @@ Starting from the first one, calculate and store the subsequent items sequential
664677
```moonbit expr
665678
fn fib2(num: Int) -> Int64 {
666679
fn aux(n: Int, map: @map.Map[Int, Int64]) -> Int64 {
667-
let result = get_or_else(map.lookup(n - 1), 1L) +
668-
get_or_else(map.lookup(n - 2), 1L)
669-
if n == num { result }
670-
else { aux(n + 1, map.insert(n, result)) }
680+
let result = get_or_else(get(map, n - 1), 1L) +
681+
get_or_else(get(map, n - 2), 1L)
682+
if n == num { result }
683+
else { aux(n + 1, put(map, n, result)) }
671684
}
672-
let map = @map.empty().insert(0, 0L).insert(1, 1L)
685+
let map = put(put(make(), 0, 0L), 1, 1L)
673686
aux(1, map)
674687
}
675688
```

course3/lecture_en.md

+27-14
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,19 @@
33
<!--
44
```moonbit
55
let pi = 3.1415
6+
7+
fn put(map: @map.Map[Int, Int64], num: Int, result: Int64) -> @map.Map[Int, Int64] {
8+
map.insert(num, result)
9+
}
10+
11+
fn get(map: @map.Map[Int, Int64], num: Int) -> Option[Int64] {
12+
map.lookup(num)
13+
}
14+
15+
fn make() -> @map.Map[Int, Int64] {
16+
@map.empty()
17+
}
18+
619
```
720
-->
821

@@ -473,9 +486,9 @@ First, let's try a top-down implementation.
473486
To cache the previous calculation results, we need a suitable data structure. Since the number of results we cache will grow with the size of the problem, the average access efficiency of the data structure should be independent of the data size. Let's call it `IntMap`, then following our standard workflow, we should now define the interfaces:
474487

475488
```moonbit no-check
476-
fn empty() -> IntMap // Create
477-
fn insert(self: IntMap, key: Int, value: Int64) -> IntMap // Store
478-
fn lookup(self: IntMap, key: Int) -> Option[Int64] // Retrieve
489+
fn make() -> IntMap // Create
490+
fn put(map: IntMap, num: Int, value: Int64) -> IntMap // Store
491+
fn get(map: IntMap, num: Int) -> Option[Int64] // Retrieve
479492
```
480493

481494
In other words, we should be able to perform the following operations using an `IntMap`: create an empty map, insert a key-value pair into it, and look up the value corresponding to a given key.
@@ -487,16 +500,16 @@ In the top-down implementation, before each computation, we first check if our d
487500
```moonbit expr
488501
fn fib1(num: Int) -> Int64 {
489502
fn aux(num: Int, map: @map.Map[Int, Int64]) -> (Int64, @map.Map[Int, Int64]) {
490-
match map.lookup(num) {
503+
match get(map, num) {
491504
Some(result) => (result, map)
492505
None => {
493506
let (result_1, map_1) = aux(num - 1, map)
494507
let (result_2, map_2) = aux(num - 2, map_1)
495-
(result_1 + result_2, map_2.insert(num, result_1 + result_2))
508+
(result_1 + result_2, put(map_2, num, result_1 + result_2))
496509
}
497510
}
498511
}
499-
let map = @map.empty().insert(1, 1L).insert(2, 1L)
512+
let map = put(put(make(), 1, 1L), 2, 1L)
500513
aux(num, map).0
501514
}
502515
```
@@ -510,15 +523,15 @@ In MoonBit, all variables are immutable by default. In order to declare a mutabl
510523
```moonbit expr
511524
fn fib1_mut(num: Int) -> Int64 {
512525
// Declare a mutable variable with let mut
513-
let mut map = @map.empty().insert(1, 1L).insert(2, 1L)
526+
let mut map = put(put(make(), 1, 1L), 2, 1L)
514527
fn aux(num: Int) -> Int64 {
515-
match map.lookup(num) {
528+
match get(map, num) {
516529
Some(result) => result
517530
None => {
518531
let result_1 = aux(num - 1)
519532
let result_2 = aux(num - 2)
520533
// Update the binding with <variable> = <expression>
521-
map = map.insert(num, result_1 + result_2)
534+
map = put(map, num, result_1 + result_2)
522535
result_1 + result_2
523536
}
524537
}
@@ -534,12 +547,12 @@ In the bottom-up implementation, we typically start from the smallest subproblem
534547
```moonbit expr
535548
fn fib2(num: Int) -> Int64 {
536549
fn aux(n: Int, map: @map.Map[Int, Int64]) -> Int64 {
537-
let result = get_or_else(map.lookup(n - 1), 1L) +
538-
get_or_else(map.lookup(n - 2), 1L)
539-
if n == num { result }
540-
else { aux(n + 1, map.insert(n, result)) }
550+
let result = get_or_else(get(map, n - 1), 1L) +
551+
get_or_else(get(map, n - 2), 1L)
552+
if n == num { result }
553+
else { aux(n + 1, put(map, n, result)) }
541554
}
542-
let map = @map.empty().insert(0, 0L).insert(1, 1L)
555+
let map = put(put(make(), 0, 0L), 1, 1L)
543556
aux(1, map)
544557
}
545558
```

0 commit comments

Comments
 (0)