Skip to content

Commit

Permalink
Merge branch 'main' into lijunchen/explicit-unit
Browse files Browse the repository at this point in the history
  • Loading branch information
bobzhang committed Mar 15, 2024
2 parents 4de9837 + 3a04a26 commit 1217809
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 28 deletions.
14 changes: 7 additions & 7 deletions assertion/assertion.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ test "assert_true.false" {

/// Assert referential equality of two values.
///
/// Returns Ok if the two arguments are the same object by reference, using the
/// `===` operator; raises an Error otherwise. Certain objects may be equal by
/// Returns Ok if the two arguments are the same object by reference, using
/// `physical_equal`; raises an Error otherwise. Certain objects may be equal by
/// value, but they are different objects in the memory. This function checks
/// the latter.
///
Expand All @@ -119,12 +119,12 @@ test "assert_true.false" {
/// assert_is(a, b)? // yields an error
/// ```
pub fn assert_is[T : Debug](a : T, b : T) -> Result[Unit, String] {
if a === b {
if physical_equal(a, b) {
Ok(())
} else {
let a = debug_string(a)
let b = debug_string(b)
Err("assertion failed for `\(a) === \(b)`")
Err("assertion failed for `\(a) is \(b)`")
}
}

Expand All @@ -145,7 +145,7 @@ test "assert_is.is.not" {
/// Assert referential inequality of two values.
///
/// Returns Ok if the two arguments are NOT the same object by reference, using
/// the `===` operator; raises an Error otherwise. Certain objects may be equal
/// `physical_equal`; raises an Error otherwise. Certain objects may be equal
/// by value, but they are different objects in the memory. This function
/// checks the latter.
///
Expand All @@ -158,12 +158,12 @@ test "assert_is.is.not" {
/// assert_is_not(a, a)? // yields an error
/// ```
pub fn assert_is_not[T : Debug](a : T, b : T) -> Result[Unit, String] {
if not(a === b) {
if not(physical_equal(a, b)) {
Ok(())
} else {
let a = debug_string(a)
let b = debug_string(b)
Err("assertion failed for `not(\(a) === \(b))`")
Err("assertion failed for `not(\(a) is \(b))`")
}
}

Expand Down
79 changes: 58 additions & 21 deletions list/list.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -486,22 +486,22 @@ test "repeat" {
/// # Example
///
/// ```
/// let ls = from_array(["1", "2", "3", "4", "5"]).separate_by("|")
/// let ls = from_array(["1", "2", "3", "4", "5"]).intersperse("|")
/// debug(ls) // output: from_array(["1", "|", "2", "|", "3", "|", "4", "|", "5"])
/// ```
pub fn separate_by[T](self : List[T], separator : T) -> List[T] {
pub fn intersperse[T](self : List[T], separator : T) -> List[T] {
match self {
Nil => Nil
Cons(head, Nil) => Cons(head, Nil)
Cons(head, tail) =>
Cons(head, Cons(separator, separate_by(tail, separator)))
Cons(head, Cons(separator, intersperse(tail, separator)))
}
}

test "separate_by" {
test "intersperse" {
let ls = from_array(["1", "|", "2", "|", "3", "|", "4", "|", "5"])
@assertion.assert_eq(
from_array(["1", "2", "3", "4", "5"]).separate_by("|"),
from_array(["1", "2", "3", "4", "5"]).intersperse("|"),
ls,
)?
}
Expand Down Expand Up @@ -554,8 +554,8 @@ test "unzip" {
/// let ls = flatten(from_array([from_array([1,2,3]), from_array([4,5,6]), from_array([7,8,9])]))
/// debug(ls) // output: from_array([1, 2, 3, 4, 5, 6, 7, 8, 9])
/// ```
pub fn flatten[T](list : List[List[T]]) -> List[T] {
match list {
pub fn flatten[T](self : List[List[T]]) -> List[T] {
match self {
Nil => Nil
Cons(head, tail) => concat(head, flatten(tail))
}
Expand Down Expand Up @@ -967,10 +967,8 @@ pub fn remove_at[T](self : List[T], index : Int) -> List[T] {
match (index, self) {
(0, Cons(_, tail)) => tail
(_, Cons(head, tail)) => Cons(head, remove_at(tail, index - 1))
(_, Nil) => {
Nil
// abort("remove_at: index out of bounds")
}
(_, Nil) => Nil
// abort("remove_at: index out of bounds")
}
}

Expand All @@ -979,8 +977,14 @@ test "remove_at" {
let rs = from_array([1, 2, 4, 5])
@assertion.assert_eq(ls.remove_at(2), rs)?
@assertion.assert_eq(ls.remove_at(0), from_array([2, 3, 4, 5]))?
@assertion.assert_eq(List::["a", "b", "c", "d", "e"].remove_at(2), List::["a", "b", "d", "e"])?
@assertion.assert_eq(List::["a", "b", "c", "d", "e"].remove_at(5), List::["a", "b", "c", "d", "e"])?
@assertion.assert_eq(
List::["a", "b", "c", "d", "e"].remove_at(2),
List::["a", "b", "d", "e"],
)?
@assertion.assert_eq(
List::["a", "b", "c", "d", "e"].remove_at(5),
List::["a", "b", "c", "d", "e"],
)?
}

/// Removes the first occurrence of the specified element from the list, if it is present.
Expand All @@ -991,20 +995,29 @@ test "remove_at" {
/// println(List::[1, 2, 3, 4, 5].remove(3))
/// // output: from_array([1, 2, 4, 5])
/// ```
pub fn remove[T : Eq](self: List[T], elem: T) -> List[T] {
pub fn remove[T : Eq](self : List[T], elem : T) -> List[T] {
match self {
Nil => {
Nil
// abort("remove: element not found")
}
Cons(head, tail) => if head == elem { tail } else { Cons(head, remove(tail, elem)) }
Nil => Nil
// abort("remove: element not found")
Cons(head, tail) =>
if head == elem {
tail
} else {
Cons(head, remove(tail, elem))
}
}
}

test "remove" {
@assertion.assert_eq(List::[1, 2, 3, 4, 5].remove(3), List::[1, 2, 4, 5])?
@assertion.assert_eq(List::["a", "b", "c", "d", "e"].remove("c"), List::["a", "b", "d", "e"])?
@assertion.assert_eq(List::["a", "b", "c", "d", "e"].remove("f"), List::["a", "b", "c", "d", "e"])?
@assertion.assert_eq(
List::["a", "b", "c", "d", "e"].remove("c"),
List::["a", "b", "d", "e"],
)?
@assertion.assert_eq(
List::["a", "b", "c", "d", "e"].remove("f"),
List::["a", "b", "c", "d", "e"],
)?
}

/// Returns true if list starts with prefix.
Expand Down Expand Up @@ -1068,3 +1081,27 @@ test "is_suffix" {
@assertion.assert_true(List::[1, 2, 3, 4, 5].is_suffix(List::[3, 4, 5]))?
@assertion.assert_false(List::[1, 2, 3, 4, 5].is_suffix(List::[3, 4, 6]))?
}

/// Similar to intersperse but with a list of values.
///
/// # Example
/// ```
/// let ls = List::[
/// List::[1, 2, 3],
/// List::[4, 5, 6],
/// List::[7, 8, 9],
/// ]
/// ls.intercalate(List::[0])
/// ```
pub fn intercalate[T](self : List[List[T]], sep : List[T]) -> List[T] {
self.intersperse(sep).flatten()
}

test "intercalate" {
let ls = List::[List::[1, 2, 3], List::[4, 5, 6], List::[7, 8, 9]]
@assertion.assert_eq(
ls.intercalate(List::[0]),
List::[1, 2, 3, 0, 4, 5, 6, 0, 7, 8, 9],
)?
}

0 comments on commit 1217809

Please sign in to comment.