Skip to content

Instantly share code, notes, and snippets.

@lenguyenthanh
Created October 15, 2019 10:58
Show Gist options
  • Save lenguyenthanh/a8a01ff5a39e93eeb0a6646fd4e83568 to your computer and use it in GitHub Desktop.
Save lenguyenthanh/a8a01ff5a39e93eeb0a6646fd4e83568 to your computer and use it in GitHub Desktop.
package arrow.typeclasses
import arrow.Kind
import arrow.core.None
import arrow.core.Option
import arrow.core.Some
import arrow.core.identity
/**
* ank_macro_hierarchy(arrow.typeclasses.FunctorFilter)
*
* A Functor with the ability to [filterMap].
*/
interface FunctorFilter<F> : Functor<F> {
/**
* A combined map and filter. Filtering is handled via Option instead of Boolean such that the output type B can be different than the input type A.
*/
fun <A, B> Kind<F, A>.filterMap(f: (A) -> Option<B>): Kind<F, B>
/**
* "Flatten" out a structure by collapsing Options.
*/
fun <A> Kind<F, Option<A>>.flattenOption(): Kind<F, A> = filterMap(::identity)
/**
* Apply a filter to a structure such that the output structure contains all A elements in the input structure that satisfy the predicate f but none
* that don't.
*/
fun <A> Kind<F, A>.filter(f: (A) -> Boolean): Kind<F, A> =
filterMap { a -> if (f(a)) Some(a) else None }
/**
* Apply a filter to a structure such that the output structure contains all instances of specified class.
*/
@Suppress("UNCHECKED_CAST")
fun <A, B> Kind<F, A>.filterIsInstance(klass: Class<B>): Kind<F, B> =
filterMap { a -> if(klass.isInstance(a)) Some(a as B) else None }
}
package arrow.core.extensions.list.functorFilter
import arrow.core.Option
import arrow.core.extensions.ListKFunctorFilter
import kotlin.Boolean
import kotlin.Class
import kotlin.Function1
import kotlin.PublishedApi
import kotlin.Suppress
import kotlin.collections.List
import kotlin.jvm.JvmName
@JvmName("filterMap")
@Suppress(
"UNCHECKED_CAST",
"USELESS_CAST",
"EXTENSION_SHADOWED_BY_MEMBER",
"UNUSED_PARAMETER"
)
fun <A, B> List<A>.filterMap(arg1: Function1<A, Option<B>>): List<B> =
arrow.core.extensions.list.functorFilter.List.functorFilter().run {
arrow.core.ListK(this@filterMap).filterMap<A, B>(arg1) as kotlin.collections.List<B>
}
@JvmName("flattenOption")
@Suppress(
"UNCHECKED_CAST",
"USELESS_CAST",
"EXTENSION_SHADOWED_BY_MEMBER",
"UNUSED_PARAMETER"
)
fun <A> List<Option<A>>.flattenOption(): List<A> =
arrow.core.extensions.list.functorFilter.List.functorFilter().run {
arrow.core.ListK(this@flattenOption).flattenOption<A>() as kotlin.collections.List<A>
}
@JvmName("filter")
@Suppress(
"UNCHECKED_CAST",
"USELESS_CAST",
"EXTENSION_SHADOWED_BY_MEMBER",
"UNUSED_PARAMETER"
)
fun <A> List<A>.filter(arg1: Function1<A, Boolean>): List<A> =
arrow.core.extensions.list.functorFilter.List.functorFilter().run {
arrow.core.ListK(this@filter).filter<A>(arg1) as kotlin.collections.List<A>
}
@JvmName("filterIsInstance")
@Suppress(
"UNCHECKED_CAST",
"USELESS_CAST",
"EXTENSION_SHADOWED_BY_MEMBER",
"UNUSED_PARAMETER"
)
fun <A, B> List<A>.filterIsInstance(arg1: Class<B>): List<B> =
arrow.core.extensions.list.functorFilter.List.functorFilter().run {
arrow.core.ListK(this@filterIsInstance).filterIsInstance<A, B>(arg1) as kotlin.collections.List<B>
}
/**
* cached extension
*/
@PublishedApi()
internal val functorFilter_singleton: ListKFunctorFilter = object :
arrow.core.extensions.ListKFunctorFilter {}
object List {
@Suppress(
"UNCHECKED_CAST",
"NOTHING_TO_INLINE"
)
inline fun functorFilter(): ListKFunctorFilter = functorFilter_singleton}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment