Skip to content

Instantly share code, notes, and snippets.

@skykanin
Created December 16, 2020 14:30
Show Gist options
  • Save skykanin/e1209c0b15286a7bb11d2727769cc16c to your computer and use it in GitHub Desktop.
Save skykanin/e1209c0b15286a7bb11d2727769cc16c to your computer and use it in GitHub Desktop.
playing around with functional kotlin
interface Semigroup<M> {
fun binary(a: M, b: M): M
}
interface Monoid<M>: Semigroup<M> {
val neutral: M
}
fun <A, M> foldMap(m: Monoid<M>, f: (A) -> M, list: List<A>): M =
list.map(f).fold(m.neutral, m::binary)
fun <A> id(a: A): A = a
fun <M> fold(m: Monoid<M>, list: List<M>): M = foldMap(m, ::id, list)
object addition: Monoid<Int> {
override val neutral: Int = 0
override fun binary(a: Int, b: Int): Int = a + b
}
object product: Monoid<Int> {
override val neutral: Int = 1
override fun binary(a: Int, b: Int): Int = a * b
}
object stringMonoid: Monoid<String> {
override val neutral: String = ""
override fun binary(a: String, b: String): String = a + b
}
class listMonoid<A>: Monoid<List<A>> {
override val neutral: List<A> = emptyList()
override fun binary(a: List<A>, b: List<A>): List<A> = a + b
}
sealed class LinkedList<out A> {
fun <B> map(f: (A) -> B): LinkedList<B> = when(this) {
is Nil -> Nil
is Cons -> Cons(f(this.head), this.tail.map(f))
}
}
object Nil : LinkedList<Nothing>() {
override fun toString(): String = "Nil"
}
data class Cons<A>(val head: A,val tail: LinkedList<A>) : LinkedList<A>()
fun main() {
val ll: LinkedList<Int> = Cons(1, Cons(2, Cons(3, Nil)))
println(ll.map { it * 10 })
println(fold(addition, (1..10).toList()))
println(fold(product, (1..10).toList()))
println(fold(stringMonoid, listOf("hello", " ", "world", "!")))
println(fold(listMonoid(), listOf(listOf(1, 2), listOf(3, 4), listOf(5, 6))))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment