Skip to content

Instantly share code, notes, and snippets.

@raulraja
Created December 22, 2021 21:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save raulraja/5bca656eb545f936b99033516ad88a5d to your computer and use it in GitHub Desktop.
Save raulraja/5bca656eb545f936b99033516ad88a5d to your computer and use it in GitHub Desktop.
Partially applied functions with selective arg application
package arrow.core
public fun interface Partial<A, B, C, D, Z> {
public operator fun invoke(a: A, b: B, c: C, d: D): Z
public fun first(a: A): Partial<Unit, B, C, D, Z> =
Partial { _, b, c, d -> invoke(a, b, c, d) }
public fun second(b: B): Partial<A, Unit, C, D, Z> =
Partial { a, _, c, d -> invoke(a, b, c, d) }
public fun third(c: C): Partial<A, B, Unit, D, Z> =
Partial { a, b, _, d -> invoke(a, b, c, d) }
public fun fourth(d: D): Partial<A, B, C, Unit, Z> =
Partial { a, b, c, _ -> invoke(a, b, c, d) }
public companion object {
public operator fun <A, B, C, D, Z> invoke(f: (A, B, C, D) -> Z): Partial<A, B, C, D, Z> =
Partial { a, b, c, d -> f(a, b, c, d) }
public operator fun <A, B, C, Z> invoke(f: (A, B, C) -> Z): Partial<A, B, C, Unit, Z> =
Partial { a, b, c, _ -> f(a, b, c) }
public operator fun <A, B, Z> invoke(f: (A, B) -> Z): Partial<A, B, Unit, Unit, Z> =
Partial { a, b, _, _ -> f(a, b) }
public operator fun <A, Z> invoke(f: (A) -> Z): Partial<A, Unit, Unit, Unit, Z> =
Partial { a, _, _, _ -> f(a) }
}
}
@JvmName("apply1")
public operator fun <A, Z> Partial<A, Unit, Unit, Unit, Z>.invoke(first: A): Z =
invoke(first, Unit, Unit, Unit)
public operator fun <B, Z> Partial<Unit, B, Unit, Unit, Z>.invoke(second: B): Z =
invoke(Unit, second, Unit, Unit)
public fun divide(num: Int, den: Int): Int =
num / den
public data class User(val id: Int, val name: String)
public fun createUser(name: String, id: Int): User =
User(id, name)
public fun main() {
val halfOf = Partial(::divide).second(2)
val ten: Int = halfOf(20)
val createUserJaneWithId = Partial(::createUser).first("Jane")
val jane = createUserJaneWithId(ten)
println(jane) //User(id=10, name=Jane)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment