Skip to content

Commit

Permalink
no need to expose arity in function names
Browse files Browse the repository at this point in the history
  • Loading branch information
konnik committed Dec 11, 2023
1 parent 64d0cbe commit 3386a4d
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 24 deletions.
18 changes: 9 additions & 9 deletions lib/src/main/kotlin/konnik/json/decode/Decoder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ fun <T> list(itemDecoder: Decoder<T>): Decoder<List<T>> = { jsonValue ->
when (jsonValue) {
is JsonValue.Array ->
jsonValue.items.fold(Ok(emptyList())) { acc, item ->
map2(acc, itemDecoder(item)) { a, b -> a + b }
map(acc, itemDecoder(item)) { a, b -> a + b }
}

else -> Err("${jsonValue.str()} is not an array")
Expand Down Expand Up @@ -198,36 +198,36 @@ fun <A, B> map(decoder: Decoder<A>, transform: (A) -> B): Decoder<B> = { jsonVal
/**
* Combine the results of two decoders using the provided function.
*/
fun <A, B, R> map2(a: Decoder<A>, b: Decoder<B>, transform: (A, B) -> R): Decoder<R> =
fun <A, B, R> map(a: Decoder<A>, b: Decoder<B>, transform: (A, B) -> R): Decoder<R> =
a.andThen { aValue ->
b.map { bValue -> transform(aValue, bValue) }
}

/**
* Combine the results of three decoders.
*/
fun <A, B, C, R> map3(a: Decoder<A>, b: Decoder<B>, c: Decoder<C>, transform: (A, B, C) -> R): Decoder<R> =
a.andThen { aValue -> map2(b, c) { bValue, cValue -> transform(aValue, bValue, cValue) } }
fun <A, B, C, R> map(a: Decoder<A>, b: Decoder<B>, c: Decoder<C>, transform: (A, B, C) -> R): Decoder<R> =
a.andThen { aValue -> map(b, c) { bValue, cValue -> transform(aValue, bValue, cValue) } }

/**
* Combine the results of four decoders.
*/
fun <A, B, C, D, R> map4(
fun <A, B, C, D, R> map(
a: Decoder<A>,
b: Decoder<B>,
c: Decoder<C>,
d: Decoder<D>,
transform: (A, B, C, D) -> R
): Decoder<R> =
a.andThen { aValue -> map3(b, c, d) { bValue, cValue, dValue -> transform(aValue, bValue, cValue, dValue) } }
a.andThen { aValue -> map(b, c, d) { bValue, cValue, dValue -> transform(aValue, bValue, cValue, dValue) } }

/**
* Combine the results of five decoders.
*
* Note: if you need to combine more than five decoders you can
* always use [andThen].
*/
fun <A, B, C, D, E, R> map5(
fun <A, B, C, D, E, R> map(
a: Decoder<A>,
b: Decoder<B>,
c: Decoder<C>,
Expand All @@ -236,7 +236,7 @@ fun <A, B, C, D, E, R> map5(
transform: (A, B, C, D, E) -> R
): Decoder<R> =
a.andThen { aValue ->
map4(b, c, d, e) { bValue, cValue, dValue, eValue ->
map(b, c, d, e) { bValue, cValue, dValue, eValue ->
transform(aValue, bValue, cValue, dValue, eValue)
}
}
Expand All @@ -259,7 +259,7 @@ fun <A, B> Decoder<A>.andThen(aToDecoderB: (A) -> Decoder<B>): Decoder<B> = { js
*/
fun <T> List<Decoder<T>>.combine(): Decoder<List<T>> =
this.fold(succeed(emptyList())) { acc, item ->
map2(acc, item) { a, b ->
map(acc, item) { a, b ->
a + b
}
}
Expand Down
18 changes: 14 additions & 4 deletions lib/src/main/kotlin/konnik/json/result/Result.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,27 @@ fun <A, B> Result<A>.map(transform: (A) -> B): Result<B> =
is Ok -> Ok(transform(this.value))
}

/**
* Maps a successful value using the provided [transform] function.
*/
@JvmName("mapDecoderAsParam")
fun <A, B> map(result: Result<A>, transform: (A) -> B): Result<B> =
when (result) {
is Err -> result
is Ok -> Ok(transform(result.value))
}

/**
* Combines two successful values using the provided [transform] function.
*/
fun <A, B, R> map2(a: Result<A>, b: Result<B>, transform: (A, B) -> R): Result<R> =
fun <A, B, R> map(a: Result<A>, b: Result<B>, transform: (A, B) -> R): Result<R> =
a.andThen { aValue -> b.map { bValue -> transform(aValue, bValue) } }

/**
* Combines three successful values using the provided [transform] function.
*/
fun <A, B, C, R> map3(a: Result<A>, b: Result<B>, c: Result<C>, transform: (A, B, C) -> R): Result<R> =
a.andThen { aValue -> map2(b, c) { bValue, cValue -> transform(aValue, bValue, cValue) } }
fun <A, B, C, R> map(a: Result<A>, b: Result<B>, c: Result<C>, transform: (A, B, C) -> R): Result<R> =
a.andThen { aValue -> map(b, c) { bValue, cValue -> transform(aValue, bValue, cValue) } }

/**
* Sequence two results where the second depends on the successful value first.
Expand All @@ -56,7 +66,7 @@ fun <A, B> Result<A>.andThen(aToResultB: (A) -> Result<B>) =
*/
fun <T> List<Result<T>>.combine(): Result<List<T>> =
this.fold(Ok(emptyList())) { acc, item ->
map2(acc, item) { a, b ->
map(acc, item) { a, b ->
a + b
}
}
2 changes: 1 addition & 1 deletion lib/src/test/kotlin/konnik/json/decode/DecoderKtTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ class DecoderKtTest {
val e: List<String>
)

val myObjDecoder = map5(
val myObjDecoder = map(
field("a") of int,
field("b") of double,
field("c") of str,
Expand Down
4 changes: 2 additions & 2 deletions lib/src/test/kotlin/konnik/json/parser/ParserKtTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ class ParserKtTest {
}

@Test
fun `decodeJson - parse and decode`() {
fun `decodeJson - parse and decode a sum type`() {
val registeredJson = """
{ "type": "registered",
"id": 42,
Expand All @@ -171,7 +171,7 @@ class ParserKtTest {
User::Guest
)

"registered" -> map4(
"registered" -> map(
field("id", int),
field("alias", str),
field("email", str),
Expand Down
16 changes: 8 additions & 8 deletions lib/src/test/kotlin/konnik/json/result/ResultKtTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ class ResultKtTest {
val err1: Result<Int> = Err("error1")
val err2: Result<Int> = Err("error2")

assertEquals(Ok(42), map2(Ok(12), Ok(30)) { a, b -> a + b })
assertEquals(err1, map2(err1, Ok(30)) { a, b -> a + b })
assertEquals(err2, map2(Ok(12), err2) { a, b -> a + b })
assertEquals(Ok(42), map(Ok(12), Ok(30)) { a, b -> a + b })
assertEquals(err1, map(err1, Ok(30)) { a, b -> a + b })
assertEquals(err2, map(Ok(12), err2) { a, b -> a + b })
}

@Test
Expand All @@ -27,11 +27,11 @@ class ResultKtTest {
val err2: Result<Int> = Err("error2")
val err3: Result<Int> = Err("error3")

assertEquals(Ok(42), map3(Ok(12), Ok(10), Ok(20)) { a, b, c -> a + b + c })
assertEquals(err1, map3(err1, Ok(10), Ok(20)) { a, b, c -> a + b + c })
assertEquals(err2, map3(Ok(12), err2, Ok(20)) { a, b, c -> a + b + c })
assertEquals(err3, map3(Ok(12), Ok(10), err3) { a, b, c -> a + b + c })
assertEquals(err1, map3(err1, err2, err3) { a, b, c -> a + b + c })
assertEquals(Ok(42), map(Ok(12), Ok(10), Ok(20)) { a, b, c -> a + b + c })
assertEquals(err1, map(err1, Ok(10), Ok(20)) { a, b, c -> a + b + c })
assertEquals(err2, map(Ok(12), err2, Ok(20)) { a, b, c -> a + b + c })
assertEquals(err3, map(Ok(12), Ok(10), err3) { a, b, c -> a + b + c })
assertEquals(err1, map(err1, err2, err3) { a, b, c -> a + b + c })
}

@Test
Expand Down

0 comments on commit 3386a4d

Please sign in to comment.