Skip to content

Instantly share code, notes, and snippets.

View nomisRev's full-sized avatar
🏂

Simon Vergauwen nomisRev

🏂
View GitHub Profile
@nomisRev
nomisRev / Console.kt
Created May 23, 2022 15:50
Console Effect handler
import arrow.core.continuations.EffectScope
import arrow.core.continuations.effect
object EndOfLine
interface Console {
context(EffectScope<EndOfLine>)
suspend fun read(): String
suspend fun String.write(): Unit
@nomisRev
nomisRev / ContextReceivers.kt
Created April 20, 2022 06:40
Context Receivers lambdas
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
import kotlin.time.ExperimentalTime
import kotlin.time.measureTimedValue
interface Logging {
fun info(msg: String): Unit
companion object Default : Logging {
override fun info(msg: String) = println("INFO: $msg")
@nomisRev
nomisRev / KtorOAuth.kt
Created February 23, 2022 08:13
Ktor Google OAuth2
import io.ktor.client.HttpClient
import io.ktor.client.call.body
import io.ktor.client.engine.cio.CIO
import io.ktor.client.request.get
import io.ktor.client.request.headers
import io.ktor.http.HttpHeaders
import io.ktor.http.HttpMethod
import io.ktor.http.HttpStatusCode
import io.ktor.server.application.call
import io.ktor.server.application.Application
@nomisRev
nomisRev / AppleTest.kt
Created January 5, 2022 18:03
Gradle Kotlin MPP appleTest task
// ./gradlew runs tests for all configured Apple targets
val appleTest = tasks.create("appleTest")
subprojects {
afterEvaluate {
val appleTargets = setOf("tvos", "watchos", "ios", "macos")
extensions.findByType<org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension>()
?.sourceSets
?.filter { appleTargets.any { target -> it.name.contains(target) } && it.name.contains("Test") }
@nomisRev
nomisRev / Validated.kt
Created December 14, 2021 14:50
Example of Arity-18 for Validated
/**
* In Arrow we only provide functions up to arity-9,
* using Tuple we can easily compose up to arity-n.
*
* A small example to show Validated#zip for arity-18
*/
fun validated(): ValidatedNel<String, Int> =
"example".invalidNel()
@nomisRev
nomisRev / Query.kt
Last active November 22, 2021 09:03
Either based transaction with Exposed. https://github.com/JetBrains/Exposed
import arrow.core.Either
import arrow.core.computations.EitherEffect
import arrow.core.computations.either
import kotlinx.coroutines.Dispatchers
import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction
typealias Query<E, A> = suspend () -> Either<E, A>
fun <E, A> query(f: suspend EitherEffect<E, *>.() -> A): Query<E, A> =
suspend { either(f) }
@nomisRev
nomisRev / Cont.kt
Created October 29, 2021 16:10
Cont<R, A> implementation in Kotlin
import arrow.core.identity
import kotlin.coroutines.Continuation
import kotlin.coroutines.resume
import kotlin.coroutines.intrinsics.suspendCoroutineUninterceptedOrReturn
import kotlin.coroutines.intrinsics.startCoroutineUninterceptedOrReturn
import kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED
interface ContEffect<R, A> {
suspend fun <B> shift(r: R): B
@nomisRev
nomisRev / List.MD
Created September 21, 2021 15:58
Slack conversations
@nomisRev
nomisRev / gist:2e4f06bcffd01833df612114814eefa0
Created September 21, 2021 15:56
Arrow Computation block `eager` vs `suspend`
The DSL uses the suspension system, but the Restricted version uses @RestrictSuspension.
This disallows any suspend function to be called inside the DSL except for the functions defined inside RestrictOptionEffect.
This means that the DSL can be evaluated immediately, or eagerly. Instead of requiring suspend.
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.coroutines/-restricts-suspension/
If you’re already inside a suspend context then it makes most sense to just use the suspend version. That’ll also allow you to use other suspending code inside the DSL
@nomisRev
nomisRev / CopurityInKotlin.md
Created August 27, 2021 11:32
Collection of small explanations I gave on Slack.

In Kotlin there is the concept of “co-pure”. The Kotlin compiler has a powerful inliner, which is very commonly used in Kotlin. An inliner takes the code from an inline fun, and puts it in the place of the call-site. So if an inline fun is pure in it’s definition, and it takes a lambda then the resulting code is pure if and only if the passed lambda is also pure. Otherwise the resulting code is impure. So the whether the resulting code pure or not depends 100% on the passed lambda.

fun pureExample(): Unit = 
  listOf(1, 2, 3).map { it + 1 } // [2, 3, 4] & pure