Skip to content

Instantly share code, notes, and snippets.

View nomisRev's full-sized avatar
🏂

Simon Vergauwen nomisRev

🏂
View GitHub Profile
sealed class Result
data class Success(val value: Int): Result()
data class Failure(val message: String): Result()
sealed class MathExpression {
fun eval(): Result = when (this) {
is Addition -> {
val resultL = left.eval()
when (resultL) {
is Failure -> resultL
is Success -> {
val resultR = right.eval()
when (resultR) {
sealed class MathExpression {
fun eval(): Result = when (this) {
is Addition -> left.eval().flatMap { ll -> right.eval().map { rr -> ll + rr } }
is Subtraction -> left.eval().flatMap { ll -> right.eval().map { rr -> ll - rr } }
is Division -> right.eval().flatMap { rr -> if (rr == 0) Failure("Division by zero") else left.eval().map { ll -> ll/rr }}
is Number -> Success(value)
}
}
sealed class Result {
fun flatMap(f: (Int) -> Result): Result = when(this) {
is Success -> f(value)
is Failure -> this
}
fun map(f: (Int) -> Int): Result = when(this) {
is Success -> Success(f(value))
is Failure -> this
}
}
sealed class GameOutcome {
data class Won(val loserName: String): GameOutcome()
data class Lost(val winnerName: String): GameOutcome()
}
@nomisRev
nomisRev / DefaultParams.kt
Last active September 23, 2017 08:55
Demo default params and the effect on calling them
fun main(args: Array<String>) {
fun higherOrder(i: Int = 0, f: (Int) -> Int): Int = f(i)
fun higherOrder2(f: (Int) -> Int, i: Int = 0): Int = f(i)
higherOrder { it + 1 }.let(::println)
higherOrder2({ it + 1 }).let(::println) //forced to use () in order to omit default param
fun value(value: Int, df: Int = 0) = value
import kategory.*
typealias Stack = ListKW<Int>
/* Normal function */
fun pop(stack: Stack): Either<String, Tuple2<Stack, Int>> =
if (stack.isNotEmpty()) (stack.drop(1).k() toT stack.first()).right()
else "Stack is empty".left()
/* Normal function */
@nomisRev
nomisRev / keyvaluestore.kt
Created November 26, 2017 14:54
KeyValueStore with Free in Kategory
@higherkind sealed class KeyValueStore<A> : KeyValueStoreKind<A> {
companion object : FreeMonadInstance<KeyValueStoreHK>
}
data class Put<A>(val key: String, val value: A) : KeyValueStore<A>()
data class Get<A>(val key: String) : KeyValueStore<Option<A>>()
data class Delete(val key: String) : KeyValueStore<Unit>()
object Clear : KeyValueStore<Unit>()
typealias FreeKeyValueStore<A> = Free<KeyValueStoreHK, A>
@nomisRev
nomisRev / BoundSetter.kt
Created February 6, 2018 08:15
Added traversal
import arrow.core.Option
import arrow.core.identity
import arrow.data.ListKW
import arrow.data.ListKWHK
import arrow.data.ListKWKind
import arrow.data.ev
import arrow.data.k
import arrow.lenses
interface BoundSetter<S, A> {
@nomisRev
nomisRev / example.kt
Created February 7, 2018 16:27
Optics DSL
@lenses data class Street(val number: Int, val name: String)
@lenses data class Address(val city: String, val street: Street)
@lenses data class Company(val name: String, val address: Address)
@lenses data class Employee(val name: String, val company: Company?)
@lenses data class Employees(val employees: ListKW<Employee>)
employees.setter().employees.each().company.nullable.address.street.name
.modify(String::toUpperCase) //modifies all employees companies address street name.
employees.setter().employees.get(0).company.nullable.address.street.name