Skip to content

Commit

Permalink
feat: add typo checker (#31)
Browse files Browse the repository at this point in the history
* feat: add typo checker

* fix: typos

* fix: `@map` -> `@immut/sorted_map`

* fix: add `_typos.toml`
  • Loading branch information
skylee03 authored Jun 4, 2024
1 parent 75bc751 commit 9c0fb10
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 10 deletions.
22 changes: 22 additions & 0 deletions .github/workflows/typo.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Check Typos
on:
pull_request

jobs:
typo-check:
runs-on: ubuntu-latest
timeout-minutes: 10
env:
FORCE_COLOR: 1
TYPOS_VERSION: v1.19.0
steps:
- name: download typos
run: curl -LsSf https://github.com/crate-ci/typos/releases/download/$TYPOS_VERSION/typos-$TYPOS_VERSION-x86_64-unknown-linux-musl.tar.gz | tar zxf - -C ${CARGO_HOME:-~/.cargo}/bin

- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}

- name: check typos
run: typos
3 changes: 3 additions & 0 deletions _typos.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[default.extend-words]
# **W**ine **I**s **N**ot an **E**mulator
ot = "ot"
2 changes: 1 addition & 1 deletion docs/01-program-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,6 @@ It is recommended to adopt a TDD workflow, namely,
3. Write the test cases
4. Implement the program

Modern softwares are typically vast in scale, making TDD a reliable workflow for their development. By creating test cases in advance, developers can efficiently identify and rectify potential errors at an early stage, while also ensuring the seamless integration of new functions without disrupting existing ones.
Modern software products are typically vast in scale, making TDD a reliable workflow for their development. By creating test cases in advance, developers can efficiently identify and rectify potential errors at an early stage, while also ensuring the seamless integration of new functions without disrupting existing ones.

Quiz: For some abnormal inputs, the sample program for the water bottles problem may fail. Can you identify them? (Hint: In MoonBit, the range of `Int` values is $-2^{31}$ to $2^{31} - 1$.)
16 changes: 8 additions & 8 deletions docs/03-functions-lists-recursion.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
```moonbit
let pi = 3.1415
fn put(map: @map.Map[Int, Int64], num: Int, result: Int64) -> @map.Map[Int, Int64] {
fn put(map: @immut/sorted_map.Map[Int, Int64], num: Int, result: Int64) -> @immut/sorted_map.Map[Int, Int64] {
map.insert(num, result)
}
fn get(map: @map.Map[Int, Int64], num: Int) -> Option[Int64] {
fn get(map: @immut/sorted_map.Map[Int, Int64], num: Int) -> Option[Int64] {
map.lookup(num)
}
fn make() -> @map.Map[Int, Int64] {
@map.empty()
fn make() -> @immut/sorted_map.Map[Int, Int64] {
@immut/sorted_map.empty()
}
```
Expand Down Expand Up @@ -264,7 +264,7 @@ The following examples help deepen our understanding of lists.
- `Cons(1, 2)`: `2` itself is not a list.
- `Cons(1, Cons(Nil, Nil))`: Items are of different types.

Like `Option[T]`, the list type `List[T]` is also genereic.
Like `Option[T]`, the list type `List[T]` is also generic.

- A list of integers is of type `List[Int]`.
- A list of strings is of type `List[String]`.
Expand Down Expand Up @@ -555,13 +555,13 @@ fn get(map: IntMap, num: Int) -> Option[Int64] // Retrieve

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.

Thanks to our paradigm of modular programming, we only need to care about the interfaces rather than the specific implementation. Therefore, there are many siutable data structures in MoonBit's standard library. In this example, we will use `@map.Map[Int, Int64]`, but we can easily replace it with another data structure, as long as it implements the interfaces we need.
Thanks to our paradigm of modular programming, we only need to care about the interfaces rather than the specific implementation. Therefore, there are many suitable data structures in MoonBit's standard library. In this example, we will use `@immut/sorted_map.Map[Int, Int64]`, but we can easily replace it with another data structure, as long as it implements the interfaces we need.

In the top-down implementation, before each computation, we first check if our desired result has been cached: if it does, we can simply use the result; if it doesn't, we calculate the result and store it in the data structure.

```moonbit expr
fn fib1(num: Int) -> Int64 {
fn aux(num: Int, map: @map.Map[Int, Int64]) -> (Int64, @map.Map[Int, Int64]) {
fn aux(num: Int, map: @immut/sorted_map.Map[Int, Int64]) -> (Int64, @immut/sorted_map.Map[Int, Int64]) {
match get(map, num) {
Some(result) => (result, map)
None => {
Expand Down Expand Up @@ -608,7 +608,7 @@ In the bottom-up implementation, we typically start from the smallest subproblem

```moonbit expr
fn fib2(num: Int) -> Int64 {
fn aux(n: Int, map: @map.Map[Int, Int64]) -> Int64 {
fn aux(n: Int, map: @immut/sorted_map.Map[Int, Int64]) -> Int64 {
let result = get_or_else(get(map, n - 1), 1L) +
get_or_else(get(map, n - 2), 1L)
if n == num { result }
Expand Down
2 changes: 1 addition & 1 deletion docs/04-tuples-structs-enums.md
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ $$
\end{array}
$$

The definition of `List[Int]` tells us that a list of intergers is either an empty list or composed of an integer with a sublist. An empty list is isomorphic to the Unit type, so it can be expressed as `1 + Int * List`. As `List` is recursive, it can be substituted with `1 + Int * 1 + Int * List`. Applying the associative law of multiplication, we get `1 + Int * (1 + Int * List)`. Continuing the substitution and simplification, we find that the set of integer lists is a distinguishable union of a single-value set, an integer set, two integer sets, and even an infinite Cartesian product of integer sets. This corresponds with reality.
The definition of `List[Int]` tells us that a list of integers is either an empty list or composed of an integer with a sublist. An empty list is isomorphic to the Unit type, so it can be expressed as `1 + Int * List`. As `List` is recursive, it can be substituted with `1 + Int * 1 + Int * List`. Applying the associative law of multiplication, we get `1 + Int * (1 + Int * List)`. Continuing the substitution and simplification, we find that the set of integer lists is a distinguishable union of a single-value set, an integer set, two integer sets, and even an infinite Cartesian product of integer sets. This corresponds with reality.

## Summary

Expand Down

0 comments on commit 9c0fb10

Please sign in to comment.