Skip to content

Commit

Permalink
Add {insert,repsert}_by_ascending_key to collection/pairs.
Browse files Browse the repository at this point in the history
  • Loading branch information
KtorZ committed Aug 30, 2024
1 parent bc5fd29 commit 32a0c78
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,10 @@
- [`cardano/governance`](https://aiken-lang.github.io/stdlib/cardano/governance.html)
- [`cardano/governance/protocol_parameters`](https://aiken-lang.github.io/stdlib/cardano/governance/protocol_parameters.html)

- New primitives in `aiken/collection/pairs`:
- [`insert_by_ascending_key`](https://aiken-lang.github.io/stdlib/aiken/collection/pairs.html#insert_by_ascending_key)
- [`repsert_by_ascending_key`](https://aiken-lang.github.io/stdlib/aiken/collection/pairs.html#repsert_by_ascending_key)

- New primitives in `aiken/crypto`:
- [`blake2b_224`](https://aiken-lang.github.io/stdlib/aiken/crypto.html#blake2b_224)
- [`keccak_256`](https://aiken-lang.github.io/stdlib/aiken/crypto.html#keccak_256)
Expand Down
112 changes: 112 additions & 0 deletions lib/aiken/collection/pairs.ak
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
//// > and thus allow for duplicate keys. This is reflected in the functions used
//// > to interact with them.

use aiken/primitive/bytearray

// ## Inspecting

/// Get all values in the alist associated with a given key.
Expand Down Expand Up @@ -482,6 +484,61 @@ test delete_last_4() {
delete_last(fixture, "a") == [Pair("a", 1), Pair("b", 2)]
}

/// Insert a value in the `Pairs` at a given key. If the key already exists,
/// the value is added in front.
///
/// ```aiken
/// use aiken/primitive/bytearray
///
/// let result =
/// []
/// |> pairs.insert_by_ascending_key(key: "foo", value: 1, compare: bytearray.compare)
/// |> pairs.insert_by_ascending_key(key: "bar", value: 2, compare: bytearray.compare)
/// |> pairs.insert_by_ascending_key(key: "foo", value: 3, compare: bytearray.compare)
///
/// result == [Pair("bar", 2), Pair("foo", 3), Pair("foo", 1)]
/// ```
pub fn insert_by_ascending_key(
self: Pairs<key, value>,
key k: key,
value v: value,
compare: fn(key, key) -> Ordering,
) -> Pairs<key, value> {
when self is {
[] ->
[Pair(k, v)]
[Pair(k2, v2), ..rest] ->
if compare(k, k2) == Less {
[Pair(k, v), ..self]
} else {
if k == k2 {
[Pair(k, v), ..self]
} else {
[Pair(k2, v2), ..insert_by_ascending_key(rest, k, v, compare)]
}
}
}
}

test insert_by_ascending_key_1() {
let m =
[]
|> insert_by_ascending_key("foo", 42, bytearray.compare)
|> insert_by_ascending_key("foo", 14, bytearray.compare)

m == [Pair("foo", 14), Pair("foo", 42)]
}

test insert_by_ascending_key_2() {
let m =
[]
|> insert_by_ascending_key("foo", 42, bytearray.compare)
|> insert_by_ascending_key("bar", 14, bytearray.compare)
|> insert_by_ascending_key("baz", 1337, bytearray.compare)

m == [Pair("bar", 14), Pair("baz", 1337), Pair("foo", 42)]
}

/// Apply a function to all key-value pairs in a alist, replacing the values.
///
/// ```aiken
Expand Down Expand Up @@ -515,6 +572,61 @@ test map_2() {
map(fixture, with: fn(_, v) { v + 1 }) == [Pair("a", 2), Pair("b", 3)]
}

/// Insert a value in the `Pairs` at a given key. If the key already exists,
/// its value is replaced.
///
/// ```aiken
/// use aiken/primitive/bytearray
///
/// let result =
/// []
/// |> pairs.repsert_by_ascending_key(key: "foo", value: 1, compare: bytearray.compare)
/// |> pairs.repsert_by_ascending_key(key: "bar", value: 2, compare: bytearray.compare)
/// |> pairs.repsert_by_ascending_key(key: "foo", value: 3, compare: bytearray.compare)
///
/// result == [Pair("bar", 2), Pair("foo", 3)]
/// ```
pub fn repsert_by_ascending_key(
self: Pairs<key, value>,
key k: key,
value v: value,
compare: fn(key, key) -> Ordering,
) -> Pairs<key, value> {
when self is {
[] ->
[Pair(k, v)]
[Pair(k2, v2), ..rest] ->
if compare(k, k2) == Less {
[Pair(k, v), ..self]
} else {
if k == k2 {
[Pair(k, v), ..rest]
} else {
[Pair(k2, v2), ..repsert_by_ascending_key(rest, k, v, compare)]
}
}
}
}

test repsert_by_ascending_key_1() {
let m =
[]
|> repsert_by_ascending_key("foo", 42, bytearray.compare)
|> repsert_by_ascending_key("foo", 14, bytearray.compare)

m == [Pair("foo", 14)]
}

test repsert_by_ascending_key_2() {
let m =
[]
|> repsert_by_ascending_key("foo", 42, bytearray.compare)
|> repsert_by_ascending_key("bar", 14, bytearray.compare)
|> repsert_by_ascending_key("baz", 1337, bytearray.compare)

m == [Pair("bar", 14), Pair("baz", 1337), Pair("foo", 42)]
}

// ## Transforming

/// Fold over the key-value pairs in a pairs. The fold direction follows keys
Expand Down

0 comments on commit 32a0c78

Please sign in to comment.