Created
August 7, 2017 12:29
-
-
Save go-cristian/ddd61d4df46e3872dc8ee33087952a8c to your computer and use it in GitHub Desktop.
Code based on Mathias's post about Monoids and Sum Types
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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