diff --git a/Kotlin/event-compose.kt b/Kotlin/event-compose.kt new file mode 100644 index 0000000..dbda16d --- /dev/null +++ b/Kotlin/event-compose.kt @@ -0,0 +1,45 @@ +import java.util.* + +class Point(x: Int, y: Int) { + private var x: Int = x + private var y: Int = y + val emitter = EventEmitter() + + init { + emitter.on("move") { event -> + val map = event as Map<*, *> + this.x += (map["x"] as Int) + this.y += (map["y"] as Int) + } + + emitter.on("clone") { callback -> + val point = Point(this.x, this.y) + (callback as (Point) -> Unit)(point) + } + + emitter.on("toString") { callback -> + (callback as (String) -> Unit)("(${this.x}, ${this.y})") + } + } +} + +class EventEmitter { + private val listeners = mutableMapOf Unit>>() + + fun on(event: String, listener: (Any) -> Unit) { + listeners.computeIfAbsent(event) { mutableListOf() }.add(listener) + } + + fun emit(event: String, arg: Any) { + listeners[event]?.forEach { it(arg) } + } +} + +// Usage +fun main() { + val p1 = Point(10, 20) + p1.emitter.emit("toString", { message: String -> println(message) }) + p1.emitter.emit("clone") { c1: Point -> + c1.emitter.emit("toString", { message: String -> println(message) }) + c1.emitter.emit("move", mapOf("x" to -5, "y" to 10)) + c1.emitter.emit("toString", { message: String -> println(message) }) diff --git a/Kotlin/monad.kt b/Kotlin/monad.kt new file mode 100644 index 0000000..c9a9947 --- /dev/null +++ b/Kotlin/monad.kt @@ -0,0 +1,46 @@ +data class Point(val x: Int, val y: Int) + +class Monad(private val value: T) { + + companion object { + fun of(value: T): Monad { + return Monad(value) + } + } + + fun map(fn: (T) -> R): Monad { + val valueCopy = deepCopy(value) + return of(fn(valueCopy)) + } + + fun chain(fn: (T) -> Monad): Monad { + val valueCopy = deepCopy(value) + return fn(valueCopy) + } + + fun ap(container: Monad): Monad { + val fn = value as (Point) -> Point + return container.map(fn) + } + + private fun deepCopy(obj: T): T { + return when (obj) { + is Point -> Point(obj.x, obj.y) as T + else -> obj + } + } +} + +val move: (Map) -> (Point) -> Point = { d -> { p -> Point(p.x + d["x"]!!, p.y + d["y"]!!) } } +val clone: (Point) -> Point = { p -> Point(p.x, p.y) } +val toString: (Point) -> Monad = { p -> Monad.of("(${p.x}, ${p.y})") } + +// Usage +fun main() { + val p1 = Monad.of(Point(10, 20)) + p1.chain(toString).map { println(it) } + val c0 = p1.map(clone) + val t1 = Monad.of(move(mapOf("x" to -5, "y" to 10))) + val c1 = t1.ap(c0) + c1.chain(toString).map { println(it) } +} diff --git a/Kotlin/prototype.kt b/Kotlin/prototype.kt new file mode 100644 index 0000000..c35e650 --- /dev/null +++ b/Kotlin/prototype.kt @@ -0,0 +1,24 @@ +class Point(var x: Int, var y: Int) { + + fun clone(): Point { + return Point(x, y) + } + + fun move(x: Int, y: Int) { + this.x += x + this.y += y + } + + override fun toString(): String { + return "(${x}, ${y})" + } +} + +// Usage +fun main() { + val p1 = Point(10, 20) + println(p1.toString()) + val c1 = p1.clone() + c1.move(-5, 10) + println(c1.toString()) +}