Last active
September 11, 2019 07:22
-
-
Save jamesward/c723838da7dc1301ce6c6d2c3582d5ea to your computer and use it in GitHub Desktop.
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
sealed class Bag<out THING> { | |
object Empty: Bag<Nothing>() | |
data class NonEmpty<out THING>(val thing: THING): Bag<THING>() | |
// Make a Bag with a THUNG in it | |
companion object { | |
fun <THUNG> make(thung: THUNG): Bag<THUNG> = NonEmpty(thung) | |
} | |
// Do stuff to the THING in the Bag by providing a thingToBagOfThang | |
// The thingToBagOfThang tells us what to do and returns new Bag which might contain a THANG | |
// If our Bag is empty to start with, then it stays empty | |
fun <THANG> doStuff(thingToBagOfThang: (THING) -> Bag<THANG>): Bag<THANG> = TODO() | |
} | |
// Converts from a string to a Bag | |
// If the string is empty, we get an empty Bag | |
// If the string is non-empty, we get a Bag containing an Int of the length of the string | |
fun toLength(s: String): Bag<Int> = with(s.length) { | |
if (this == 0) | |
Bag.Empty | |
else | |
Bag.make(this) | |
} | |
// Basic Expectations | |
Bag.make("asdf").doStuff(::toLength) == Bag.make(4) | |
Bag.make("").doStuff(::toLength) == Bag.Empty | |
Bag.Empty.doStuff(::toLength) == Bag.Empty | |
// Monad Rules | |
// Left Identity Law | |
Bag.make("asdf").doStuff(::toLength) == toLength("asdf") | |
Bag.make("").doStuff(::toLength) == toLength("") | |
Bag.make("asdf").doStuff { Bag.Empty } == Bag.Empty | |
// Right Identity Law | |
Bag.make("asdf").doStuff(Bag<String>::make) == Bag.make("asdf") | |
Bag.make("").doStuff(Bag<String>::make) == Bag.make("") | |
Bag.Empty.doStuff(Bag<String>::make) == Bag.Empty | |
// Associativity Law | |
fun reverse(s: String): Bag<String> = if (s.isEmpty()) Bag.Empty else Bag.make(s.reversed()) | |
Bag.make("asdf").doStuff(::reverse).doStuff(::toLength) == Bag.make("asdf").doStuff { reverse(it).doStuff(::toLength) } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment