Skip to content

Commit

Permalink
Add FilterIndex instances for java_util
Browse files Browse the repository at this point in the history
  • Loading branch information
nomisRev committed Feb 9, 2018
1 parent f962a3f commit 28a777c
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ import arrow.optics.instances.StringFilterIndexInstance
object StringFilterIndexInstanceImplicits {
@JvmStatic
fun instance(): StringFilterIndexInstance = StringFilterIndexInstance
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package java_util

import arrow.Kind
import arrow.core.Predicate
import arrow.core.toT
import arrow.data.ListK
import arrow.data.k
import arrow.data.traverse
import arrow.optics.Traversal
import arrow.optics.typeclasses.FilterIndex
import arrow.typeclasses.Applicative

interface MapFilterIndexInstance<K, V> : FilterIndex<Map<K, V>, K, V> {
override fun filter(p: Predicate<K>) = object : Traversal<Map<K, V>, V> {
override fun <F> modifyF(FA: Applicative<F>, s: Map<K, V>, f: (V) -> Kind<F, V>): Kind<F, Map<K, V>> =
ListK.traverse().traverse(s.toList().k(), { (k, v) ->
FA.map(if (p(k)) f(v) else FA.pure(v)) {
k to it
}
}, FA).let {
FA.map(it) {
it.toMap()
}
}
}
}

object MapFilterIndexInstanceImplicits {
@JvmStatic
fun <K, V> instance(): FilterIndex<Map<K, V>, K, V> = object : MapFilterIndexInstance<K, V> {}
}

interface ListFilterIndexInstance<A> : FilterIndex<List<A>, Int, A> {
override fun filter(p: (Int) -> Boolean): Traversal<List<A>, A> = object : Traversal<List<A>, A> {
override fun <F> modifyF(FA: Applicative<F>, s: List<A>, f: (A) -> Kind<F, A>): Kind<F, List<A>> =
ListK.traverse().traverse(s.mapIndexed { index, a -> a toT index }.k(), { (a, j) ->
if (p(j)) f(a) else FA.pure(a)
}, FA).let {
FA.map(it) {
it.list
}
}
}
}

object ListFilterIndexInstanceImplicits {
@JvmStatic
fun <A> instance(): FilterIndex<List<A>, Int, A> = object : ListFilterIndexInstance<A> {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import arrow.test.generators.genMapK
import arrow.test.generators.genNonEmptyList
import arrow.test.generators.genSequenceK
import arrow.test.laws.TraversalLaws
import arrow.typeclasses.Eq
import io.kotlintest.KTestJUnitRunner
import io.kotlintest.matchers.shouldNotBe
import io.kotlintest.properties.Gen
Expand All @@ -27,9 +28,11 @@ class FilterIndexInstanceTest : UnitSpec() {

"instances can be resolved implicitly" {
filterIndex<ListK<String>, Int, String>() shouldNotBe null
filterIndex<List<String>, Int, String>() shouldNotBe null
filterIndex<NonEmptyList<String>, Int, String>() shouldNotBe null
filterIndex<SequenceK<Char>, Int, Char>() shouldNotBe null
filterIndex<MapK<Char, Int>, String, Int>() shouldNotBe null
filterIndex<Map<Char, Int>, String, Int>() shouldNotBe null
filterIndex<String, Int, Char>() shouldNotBe null
}

Expand All @@ -40,6 +43,14 @@ class FilterIndexInstanceTest : UnitSpec() {
funcGen = genFunctionAToB(Gen.string())
))

testLaws(TraversalLaws.laws(
traversal = FilterIndex.filterIndex<List<String>, Int, String> { true },
aGen = Gen.list(Gen.string()),
bGen = Gen.string(),
funcGen = genFunctionAToB(Gen.string()),
EQA = Eq.any()
))

testLaws(TraversalLaws.laws(
traversal = FilterIndex.filterIndex<NonEmptyList<String>, Int, String> { true },
aGen = genNonEmptyList(Gen.string()),
Expand All @@ -61,6 +72,14 @@ class FilterIndexInstanceTest : UnitSpec() {
funcGen = genFunctionAToB(Gen.int())
))

testLaws(TraversalLaws.laws(
traversal = FilterIndex.filterIndex<Map<Char, Int>, Char, Int> { true },
aGen = genMapK(genChars(), genIntSmall()),
bGen = Gen.int(),
funcGen = genFunctionAToB(Gen.int()),
EQA = Eq.any()
))

testLaws(TraversalLaws.laws(
traversal = FilterIndex.filterIndex<String, Int, Char> { true },
aGen = Gen.string(),
Expand Down

0 comments on commit 28a777c

Please sign in to comment.