Skip to content

Instantly share code, notes, and snippets.

@go-cristian
Created August 7, 2017 12:29
Show Gist options
  • Save go-cristian/ddd61d4df46e3872dc8ee33087952a8c to your computer and use it in GitHub Desktop.
Save go-cristian/ddd61d4df46e3872dc8ee33087952a8c to your computer and use it in GitHub Desktop.
Code based on Mathias's post about Monoids and Sum Types
import java.util.Arrays
val inventory = Array<Elem>(size = 3) { Empty }
fun main(args: Array<String>) {
val sword1 = Sword("Sword 1")
val sword2 = Sword("Sword 2")
val pickaxe = Pickaxe("Pickaxe 1")
val item1 = Item(sword1)
val item2 = Item(sword2)
val item3 = Item(pickaxe)
val stack = item1 + item2 // creates an ItemStack
val stillItem1 = Empty + item1 // this compiles and works!
inventory[0] = item1
inventory[1] = item2
inventory[2] = item3
move(inventory, 0, 1)
move(inventory, 2, 1)
println(Arrays.deepToString(inventory))
}
fun move(inventory: Array<Elem>, from: Int, to: Int) {
inventory[to] = inventory[to] + inventory[from]
inventory[from] = Empty
}
sealed class GameObject
data class Pickaxe(val name: String) : GameObject()
data class Sword(val name: String) : GameObject()
sealed class Elem {
abstract operator fun plus(el: Elem): Elem
inline fun yieldFirst(f: (Item) -> Unit) =
when (this) {
is Empty -> Unit
is Item -> f(this)
is ItemStack -> f(this.items.first())
}
}
object Empty : Elem() {
override fun plus(e: Elem): Elem = e
}
data class Item(val obj: GameObject) : Elem() {
override fun plus(el: Elem): Elem =
when (el) {
is Empty -> this
is Item -> ItemStack(setOf(this, el))
is ItemStack -> ItemStack(el.items + this)
}
}
data class ItemStack(val items: Set<Item>) : Elem() {
init {
require(items.size > 1) { "Stacks must contain > 1 items" }
}
override fun plus(el: Elem): Elem =
when (el) {
is Empty -> this
is Item -> ItemStack(this.items + el)
is ItemStack -> ItemStack(this.items + el.items)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment