addamsson
07/14/2019, 11:07 AMraulraja
07/14/2019, 11:44 AMraulraja
07/14/2019, 11:45 AMraulraja
07/14/2019, 11:46 AMraulraja
07/14/2019, 11:48 AMraulraja
07/14/2019, 11:49 AMsimon.vergauwen
07/14/2019, 12:12 PMfor Arrow to become MPP we are developing typeclasses of KEEP-87 as a compiler pluginIs this blocking core to be MPP?
Monad#fx
and @higherkind
seem the blockers to me. @higherkind
could temporarly be replaced by its boilerplate.
If we can find a (temp) solution to seperate Monad#fx
that would open the door to make core MPP already.addamsson
07/14/2019, 12:14 PMaddamsson
07/14/2019, 12:15 PMaddamsson
07/14/2019, 12:15 PMaddamsson
07/14/2019, 12:15 PMaddamsson
07/14/2019, 12:16 PMsimon.vergauwen
07/14/2019, 12:16 PMaddamsson
07/14/2019, 12:16 PMaddamsson
07/14/2019, 12:35 PMaddamsson
07/14/2019, 12:36 PMaddamsson
07/14/2019, 12:36 PMaddamsson
07/14/2019, 12:36 PMsimon.vergauwen
07/14/2019, 12:37 PMaddamsson
07/14/2019, 12:37 PMaddamsson
07/14/2019, 12:37 PMsimon.vergauwen
07/14/2019, 12:38 PMaddamsson
07/14/2019, 12:38 PMsimon.vergauwen
07/14/2019, 12:39 PMaddamsson
07/14/2019, 12:39 PMaddamsson
07/14/2019, 12:39 PMsimon.vergauwen
07/14/2019, 12:39 PMaddamsson
07/14/2019, 12:39 PMaddamsson
07/14/2019, 12:39 PMsimon.vergauwen
07/14/2019, 12:40 PMaddamsson
07/14/2019, 12:40 PMaddamsson
07/14/2019, 12:40 PMaddamsson
07/14/2019, 12:41 PMsimon.vergauwen
07/14/2019, 12:41 PMfor
comphresions/do-notation, for perf and MPP reasons we’ll replace this with compiler plugins.addamsson
07/14/2019, 12:41 PMaddamsson
07/14/2019, 12:41 PMsimon.vergauwen
07/14/2019, 12:41 PMaddamsson
07/14/2019, 12:42 PMsimon.vergauwen
07/14/2019, 12:42 PMaddamsson
07/14/2019, 2:07 PMaddamsson
07/14/2019, 2:07 PMaddamsson
07/14/2019, 2:07 PMaddamsson
07/14/2019, 2:09 PMValue
(which they realized they need to remove)addamsson
07/14/2019, 2:09 PMIterable
addamsson
07/14/2019, 2:10 PMOption
which is an empty Iterable
if it is None
and an Iterable
with 1 element if it is Some
addamsson
07/14/2019, 2:10 PMEither
?addamsson
07/14/2019, 2:10 PMsimon.vergauwen
07/14/2019, 2:13 PMIterable
is the wrong abstraction here. fold
is what you want to use instead, it's abstracted over by Foldable
. Which is the polymorphic way of providing this API.addamsson
07/14/2019, 2:16 PMaddamsson
07/14/2019, 2:17 PMsimon.vergauwen
07/14/2019, 2:32 PMMonad
(flatMap), `Foldable`(fold), Traverse
(traverse), FunctorFilter
(filter) etcsimon.vergauwen
07/14/2019, 2:32 PMsimon.vergauwen
07/14/2019, 2:33 PMaddamsson
07/14/2019, 2:40 PMaddamsson
07/14/2019, 2:40 PMIterable
with these?addamsson
07/14/2019, 2:41 PMaddamsson
07/14/2019, 2:41 PMaddamsson
07/14/2019, 2:41 PMmyMap.toPersistentMap().map { (key, value) -> ...}.fold { ... }
addamsson
07/14/2019, 2:42 PMIterable
so I need to supply specializations for all of them which work with `PersistentCollection`saddamsson
07/14/2019, 2:43 PMaddamsson
07/14/2019, 2:44 PMaddamsson
07/14/2019, 2:44 PMaddamsson
07/14/2019, 2:46 PMaddamsson
07/14/2019, 2:46 PMaddamsson
07/14/2019, 2:46 PMsimon.vergauwen
07/14/2019, 2:56 PMsimon.vergauwen
07/14/2019, 2:57 PMsimon.vergauwen
07/14/2019, 2:58 PMIterable
on your persistent collections. This way you can avoid getting tangled into the extensions functions of the std.simon.vergauwen
07/14/2019, 2:59 PMsimon.vergauwen
07/14/2019, 3:00 PMobject PersistedMapFunctor
available is enough for the compiler to know map
exists for PersistentMap
.addamsson
07/14/2019, 3:18 PMThis way you can avoid getting tangled into the extensions functions of the std.
This is what I implied, yes!addamsson
07/14/2019, 3:19 PMarrow
addamsson
07/14/2019, 3:19 PM./gradlew clean build
resulted in a wall of text of compilation errors. Am I missing something? A switch maybe?addamsson
07/14/2019, 3:20 PMD:\dev\forks\arrow\modules\validation\arrow-validation\build\generated\source\kaptKotlin\main\extension\arrow\validation\refinedTypes\numeric\either\nonZero\EitherNonZero.kt: (18, 47): Type argument is not within its bounds: should be subtype of 'Number'
raulraja
07/14/2019, 9:29 PMaddamsson
07/15/2019, 1:07 PMaddamsson
07/15/2019, 1:07 PMaddamsson
07/15/2019, 1:07 PMaddamsson
07/15/2019, 1:09 PMaddamsson
07/15/2019, 1:25 PMaddamsson
07/15/2019, 1:25 PMaddamsson
07/15/2019, 1:25 PMaddamsson
07/15/2019, 1:42 PMaddamsson
07/15/2019, 1:42 PMraulraja
07/15/2019, 3:16 PMaddamsson
07/15/2019, 4:12 PMaddamsson
07/15/2019, 4:12 PM./gradlew clean build
takes 32m?pakoito
07/15/2019, 4:15 PMpakoito
07/15/2019, 4:15 PMpakoito
07/15/2019, 4:15 PMpakoito
07/15/2019, 4:15 PMaddamsson
07/15/2019, 4:16 PMaddamsson
07/15/2019, 4:16 PMaddamsson
07/15/2019, 5:50 PMPersistentMap
using Arrow with the plain old JVM target (no MPP) just to see how it works, although I have one question:addamsson
07/15/2019, 5:50 PMraulraja
07/15/2019, 5:51 PMremove
?addamsson
07/15/2019, 5:51 PMfun remove(element: E): PersistentMap<E>
addamsson
07/15/2019, 5:51 PMraulraja
07/15/2019, 5:51 PMaddamsson
07/15/2019, 5:55 PMaddamsson
07/15/2019, 5:55 PMelement
addamsson
07/15/2019, 5:55 PMaddamsson
07/15/2019, 5:58 PMFunctorFilter
raulraja
07/15/2019, 5:58 PMaddamsson
07/15/2019, 5:58 PMraulraja
07/15/2019, 5:58 PMremove
operation to wherever it fitsraulraja
07/15/2019, 5:59 PMaddamsson
07/15/2019, 6:00 PMfilter
?addamsson
07/15/2019, 6:01 PMremove
is a specialized version of filter
addamsson
07/15/2019, 6:01 PMaddamsson
07/15/2019, 6:01 PMlist.filter { it != element}
addamsson
07/15/2019, 6:01 PMO(n)
vs O(1)
raulraja
07/15/2019, 6:02 PMraulraja
07/15/2019, 6:02 PMaddamsson
07/15/2019, 6:02 PMeq
for E
and which has filter
addamsson
07/15/2019, 6:02 PMaddamsson
07/15/2019, 6:03 PMFunctorFilter
and Eq
addamsson
07/15/2019, 6:03 PMremove
to FunctorFilter
and have the default implementation which is O(n)
addamsson
07/15/2019, 6:04 PMO(1)
version for PersistentMap
addamsson
07/15/2019, 6:04 PMraulraja
07/15/2019, 6:04 PMfun <F, A> Kind<F, A>.remove(a: A): Kind<F, A> =
if (this.contains(a)) this.filter { it == a }
else this
addamsson
07/15/2019, 6:04 PMEq
comes into the pictureraulraja
07/15/2019, 6:04 PMaddamsson
07/15/2019, 6:05 PMaddamsson
07/15/2019, 6:06 PMaddamsson
07/15/2019, 6:06 PMKind<F, A>
addamsson
07/15/2019, 6:06 PMKind<ForPeristentMap, A>
?simon.vergauwen
07/15/2019, 6:10 PMO(n)
impl would exist in FunctorFilter
and a fast impl would override the default in FunctorFilter<PersistentMapOf<Keys>>
and FunctorFilter<ForPersistentSet>
raulraja
07/15/2019, 6:11 PMaddamsson
07/15/2019, 6:11 PMaddamsson
07/15/2019, 6:11 PMaddamsson
07/15/2019, 6:11 PMaddamsson
07/15/2019, 6:11 PMaddamsson
07/15/2019, 6:11 PMaddamsson
07/15/2019, 6:12 PMraulraja
07/15/2019, 6:12 PMfun <A> Kind<F, A>.remove(a: A): Kind<F, A> =
mapFilter {
if (a == it) Some(it)
else None
}
raulraja
07/15/2019, 6:13 PMraulraja
07/15/2019, 6:13 PM==
is where the equality plays a roleraulraja
07/15/2019, 6:14 PMremoveIf
etc…raulraja
07/15/2019, 6:15 PMsimon.vergauwen
07/15/2019, 6:15 PMfold
code insteadraulraja
07/15/2019, 6:16 PMraulraja
07/15/2019, 6:16 PMcontains
etc.raulraja
07/15/2019, 6:17 PMpakoito
07/15/2019, 6:17 PMif (a == it) Some(it)
==> one thing to mention, all maps in Haskell use Eq and Ord for keyspakoito
07/15/2019, 6:18 PMaddamsson
07/15/2019, 6:22 PMFoldable
seems like a reasonable choice if we care about utilityaddamsson
07/15/2019, 6:22 PMFunctorFilter
addamsson
07/15/2019, 6:22 PMEq
should be used instead of ==
addamsson
07/15/2019, 6:22 PMEq
addamsson
07/15/2019, 6:23 PMaddamsson
07/15/2019, 6:23 PMarrow-core-data
?addamsson
07/15/2019, 6:23 PMcore
concept?simon.vergauwen
07/15/2019, 6:28 PMcore
not perse, if the module is small enough I'd say yes.simon.vergauwen
07/15/2019, 6:29 PMraulraja
07/15/2019, 6:34 PMremove
would go in FunctorFilter or Foldable in core and the actual collection implementations datatypes and extensions a arrow-persistent-collections
or similar named moduleaddamsson
07/15/2019, 7:55 PMFunctorFilter
or Foldable
?addamsson
07/15/2019, 7:55 PMaddamsson
07/15/2019, 8:04 PMPersistentMap
on a branch in my Arrow fork and open a PR you can reviewaddamsson
07/15/2019, 8:04 PMaddamsson
07/15/2019, 8:04 PMPersistentSet
+ PersistentList
together with PersistentMap
in one go)pakoito
07/15/2019, 8:08 PMpakoito
07/15/2019, 8:08 PM1. I’ll finish my port of persistent data structures to Kotlin in my own projectwhat’s missing/necessary?
addamsson
07/15/2019, 8:10 PMaddamsson
07/15/2019, 8:10 PMaddamsson
07/15/2019, 8:13 PMaddamsson
07/15/2019, 8:14 PMcommon
project so retrofitting to MPP will be a no-op 😄pakoito
07/15/2019, 8:18 PMpakoito
07/15/2019, 8:18 PMpakoito
07/15/2019, 8:18 PMthen I have to refactor the type hierarchy to align it with ArrowI’m curious about this, if the code is shared through inheritance
addamsson
07/15/2019, 8:20 PMaddamsson
07/15/2019, 8:20 PMaddamsson
07/15/2019, 8:20 PMpakoito
07/15/2019, 8:38 PMpakoito
07/15/2019, 8:38 PMaddamsson
07/15/2019, 8:39 PMaddamsson
07/15/2019, 8:39 PMaddamsson
07/15/2019, 9:07 PMnull
keys should be allowed?addamsson
07/15/2019, 9:07 PMpakoito
07/15/2019, 9:08 PMpakoito
07/15/2019, 9:08 PMpakoito
07/15/2019, 9:08 PMpakoito
07/15/2019, 9:08 PMpakoito
07/15/2019, 9:09 PMaddamsson
07/15/2019, 9:10 PMraulraja
07/15/2019, 11:12 PMraulraja
07/15/2019, 11:13 PMraulraja
07/15/2019, 11:16 PMaddamsson
07/16/2019, 7:10 AMaddamsson
07/16/2019, 7:11 AM<K, V>
so null
is theoretically acceptedaddamsson
07/16/2019, 12:16 PMinterface
for HAMT right now:addamsson
07/16/2019, 12:17 PMinterface HashArrayMappedTrie<K, V> : Iterable<Tuple2<K, V>> {
val isEmpty: Boolean
val size: Int
operator fun get(key: K): Option<out V>
fun containsKey(key: K): Boolean
fun put(key: K, value: V): HashArrayMappedTrie<K, V>
fun remove(key: K): HashArrayMappedTrie<K, V>
fun keysIterator(): Iterator<K>
fun valuesIterator(): Iterator<V>
}
addamsson
07/16/2019, 12:18 PMaddamsson
07/16/2019, 12:21 PMOption
instead of the VAVR oneraulraja
07/16/2019, 12:28 PMraulraja
07/16/2019, 12:29 PMraulraja
07/16/2019, 12:31 PMaddamsson
07/16/2019, 12:56 PMaddamsson
07/16/2019, 12:56 PMMapK
addamsson
07/16/2019, 12:56 PMaddamsson
07/16/2019, 3:07 PMaddamsson
07/16/2019, 3:08 PMaddamsson
07/17/2019, 11:06 AMcore/arrow-persistent-collections
as a module for the implementations?raulraja
07/17/2019, 11:09 AMaddamsson
07/17/2019, 11:09 AMaddamsson
07/17/2019, 11:09 AMmaster
?raulraja
07/17/2019, 11:10 AMraulraja
07/17/2019, 11:10 AMaddamsson
07/17/2019, 11:12 AMaddamsson
07/17/2019, 11:13 AMarrow-persistent-collections
in the modules
folder, I'll branch from master
and I'll augment Foldable
. If that's not gonna work I'll use FunctorFilter
addamsson
07/17/2019, 11:13 AMMapK
as an examplepakoito
07/17/2019, 11:13 AMaddamsson
07/17/2019, 11:13 AMk()
function btw which creates a ListK
form a List
?addamsson
07/17/2019, 11:13 AMpakoito
07/17/2019, 11:13 AMpakoito
07/17/2019, 11:14 AMk()
is how you wrap stuffpakoito
07/17/2019, 11:14 AMpakoito
07/17/2019, 11:14 AMpakoito
07/17/2019, 11:14 AMaddamsson
07/17/2019, 11:14 AMk
and the prefix K
means?pakoito
07/17/2019, 11:14 AMaddamsson
07/17/2019, 11:15 AMpakoito
07/17/2019, 11:15 AMraulraja
07/17/2019, 11:17 AMraulraja
07/17/2019, 11:17 AMaddamsson
07/17/2019, 11:18 AMraulraja
07/17/2019, 11:18 AMaddamsson
07/17/2019, 11:18 AMraulraja
07/17/2019, 11:18 AMraulraja
07/17/2019, 11:18 AMraulraja
07/17/2019, 11:18 AMaddamsson
07/17/2019, 11:18 AMraulraja
07/17/2019, 11:19 AMaddamsson
07/17/2019, 11:19 AMraulraja
07/17/2019, 11:19 AMaddamsson
07/17/2019, 11:19 AMraulraja
07/17/2019, 11:20 AMaddamsson
07/17/2019, 11:20 AMaddamsson
07/17/2019, 11:20 AMraulraja
07/17/2019, 11:20 AMraulraja
07/17/2019, 11:20 AMaddamsson
07/17/2019, 11:21 AMsimon.vergauwen
07/17/2019, 11:23 AMsimon.vergauwen
07/17/2019, 11:24 AMraulraja
07/17/2019, 11:25 AMraulraja
07/17/2019, 11:26 AMraulraja
07/17/2019, 11:26 AMraulraja
07/17/2019, 11:26 AMaddamsson
07/17/2019, 11:29 AMaddamsson
07/17/2019, 11:29 AMaddamsson
07/17/2019, 11:29 AMsimon.vergauwen
07/17/2019, 11:30 AMaddamsson
07/17/2019, 11:30 AMaddamsson
07/17/2019, 11:30 AMsimon.vergauwen
07/17/2019, 11:30 AMsimon.vergauwen
07/17/2019, 11:31 AMraulraja
07/17/2019, 11:32 AMaddamsson
07/17/2019, 11:32 AMraulraja
07/17/2019, 11:32 AMaddamsson
07/17/2019, 11:34 AMaddamsson
07/17/2019, 11:34 AMaddamsson
07/17/2019, 11:34 AMraulraja
07/17/2019, 11:35 AMaddamsson
07/17/2019, 11:35 AMraulraja
07/17/2019, 11:36 AMaddamsson
07/17/2019, 11:36 AMaddamsson
07/17/2019, 11:36 AMraulraja
07/17/2019, 11:36 AMaddamsson
07/17/2019, 11:36 AMraulraja
07/17/2019, 11:38 AMaddamsson
07/17/2019, 11:38 AMaddamsson
07/17/2019, 11:38 AMraulraja
07/17/2019, 11:38 AMaddamsson
07/17/2019, 11:38 AMaddamsson
07/17/2019, 11:39 AMraulraja
07/17/2019, 11:41 AMaddamsson
07/17/2019, 11:45 AMaddamsson
07/17/2019, 11:45 AMaddamsson
07/17/2019, 11:45 AMraulraja
07/17/2019, 11:46 AMaddamsson
07/17/2019, 11:47 AMaddamsson
07/17/2019, 11:48 AMaddamsson
07/17/2019, 11:48 AMaddamsson
07/18/2019, 9:22 AMMapK
addamsson
07/18/2019, 9:22 AMMap
in our PersistentMap
addamsson
07/18/2019, 9:22 AMMap
which just don't make sense in our implementationaddamsson
07/18/2019, 9:24 AMmodules/persistent/arrow-persistent-data-structures
because it is better aligned with the naming I see thereaddamsson
07/18/2019, 9:24 AMraulraja
07/18/2019, 11:03 AMaddamsson
07/18/2019, 11:32 AMTuple2
?addamsson
07/18/2019, 11:32 AM@extension
interface PersistentMapFoldable<K, V> : Foldable<Tuple2<K, V>> {
override fun <A, B> Kind<Tuple2<K, V>, A>.foldLeft(b: B, f: (B, A) -> B): B {
TODO("not implemented")
}
override fun <A, B> Kind<Tuple2<K, V>, A>.foldRight(lb: Eval<B>, f: (A, Eval<B>) -> Eval<B>): Eval<B> {
TODO("not implemented")
}
}
addamsson
07/18/2019, 11:33 AMMapK
uses the partially applied type and only folds keysaddamsson
07/18/2019, 11:36 AMaddamsson
07/18/2019, 11:36 AMwith(intFold) {
"Folding a list of ints" {
forAll(Gen.list(<http://Gen.int|Gen.int>())) { ints ->
fold(Int.monoid(), ints.k()) == ints.sum()
}
}
}
addamsson
07/18/2019, 11:36 AMraulraja
07/18/2019, 11:51 AMraulraja
07/18/2019, 11:51 AMaddamsson
07/18/2019, 11:51 AMaddamsson
07/18/2019, 11:51 AMaddamsson
07/18/2019, 11:51 AM@JvmName("orEmpty")
@Suppress(
"UNCHECKED_CAST",
"USELESS_CAST",
"EXTENSION_SHADOWED_BY_MEMBER",
"UNUSED_PARAMETER"
)
fun <K, V, A> orEmpty(arg0: Applicative<Tuple2<K, V>>, arg1: Monoid<A>): Tuple2<K, V, A> =
arrow.core.Tuple2
.foldable<K, V>()
.orEmpty<A>(arg0, arg1) as arrow.core.Tuple2<K, V, A>
raulraja
07/18/2019, 11:51 AMaddamsson
07/18/2019, 11:52 AMraulraja
07/18/2019, 11:52 AMraulraja
07/18/2019, 11:52 AMaddamsson
07/18/2019, 11:53 AMraulraja
07/18/2019, 11:53 AMaddamsson
07/18/2019, 11:53 AMaddamsson
07/18/2019, 11:53 AMFoldable<Tuple2<K, V>>
is not workingraulraja
07/18/2019, 12:00 PMraulraja
07/18/2019, 12:00 PMraulraja
07/18/2019, 12:00 PMraulraja
07/18/2019, 12:01 PMaddamsson
07/18/2019, 12:05 PMaddamsson
07/18/2019, 12:05 PMaddamsson
07/18/2019, 12:05 PMaddamsson
07/18/2019, 12:05 PMforAll {}
constuct is usedraulraja
07/18/2019, 12:06 PM==
or Eq
usually is the wayaddamsson
07/18/2019, 12:07 PMaddamsson
07/18/2019, 12:07 PMaddamsson
07/18/2019, 12:07 PM"Should be able to use fold as a filter" {
val result = listOf(1, 2, 3, 4).k().foldLeft(listOf<Int>()) { list, next ->
if (next == 2) {
list
} else list.plus(next)
}
with(result) {
forAll {
result == listOf(0, 3, 4)
}
}
}
addamsson
07/18/2019, 12:07 PMresult
is list(1, 3, 4)
addamsson
07/18/2019, 12:07 PMFoldTest
addamsson
07/18/2019, 12:08 PMFoldable
is sufficient to implement remove
what we've been talking about yesterdayaddamsson
07/18/2019, 12:08 PMaddamsson
07/18/2019, 12:12 PMaddamsson
07/18/2019, 12:12 PMsimon.vergauwen
07/18/2019, 12:13 PMforAll
passed but not sure how it work without arguments.simon.vergauwen
07/18/2019, 12:13 PMsimon.vergauwen
07/18/2019, 12:15 PMwith(result)
, to result shouldBe listOf(0, 3, 4)
. Does it fail then?addamsson
07/18/2019, 12:18 PMaddamsson
07/18/2019, 12:36 PMaddamsson
07/18/2019, 12:36 PMaddamsson
07/18/2019, 12:38 PMaddamsson
07/18/2019, 12:39 PMFoldable
is not a Monoid
we don't have compose
addamsson
07/18/2019, 12:40 PMidentity
addamsson
07/18/2019, 12:40 PMfun <A> Kind<F, A>.remove(element: A): Kind<F, A> = foldLeft(???) { foldable, next ->
if(element == next) {
foldable
} else foldable ??? next
}
simon.vergauwen
07/18/2019, 12:41 PMfun <A> Kind<F, A>.remove(element: A, MA: Monoid<A>): Kind<F, A>
in Foldable
.simon.vergauwen
07/18/2019, 12:42 PMfun <A> Kind<F, A>.remove(element: A): Kind<F, A>
can only live in FunctorFilter
.addamsson
07/18/2019, 12:42 PMaddamsson
07/18/2019, 12:42 PMaddamsson
07/18/2019, 12:42 PMfun <A> Kind<F, A>.remove(element: A, monoid: Monoid<A>): Kind<F, A> = foldLeft(monoid.empty()) { foldable, next ->
if(element == next) {
foldable
} else monoid.???
}
addamsson
07/18/2019, 12:46 PMsimon.vergauwen
07/18/2019, 12:46 PMaddamsson
07/18/2019, 12:46 PMaddamsson
07/18/2019, 12:46 PMsimon.vergauwen
07/18/2019, 12:47 PMaddamsson
07/18/2019, 12:47 PMsimon.vergauwen
07/18/2019, 12:47 PMMonoidK
for F
.addamsson
07/18/2019, 12:47 PMsimon.vergauwen
07/18/2019, 12:48 PMFunctorFilter
.addamsson
07/18/2019, 12:49 PM0.2%
simon.vergauwen
07/18/2019, 12:52 PMremove
with filter
makes more sense to me than grouping it with fold
.addamsson
07/18/2019, 12:52 PMaddamsson
07/18/2019, 12:53 PMcombine
is an extension functionaddamsson
07/18/2019, 12:53 PMadd
the next element to itaddamsson
07/18/2019, 12:55 PMaddamsson
07/18/2019, 12:55 PMfun <A> Kind<F, A>.remove(element: A, MF: MonoidK<F>, MA: Monoid<A>): Kind<F, A> = MF.run {
foldLeft(empty()) { acc, a ->
if (a == element) {
acc
} else ???
}
}
addamsson
07/18/2019, 12:56 PMaddamsson
07/18/2019, 12:56 PMMonoid<MonoidK<F>>
?addamsson
07/18/2019, 12:56 PMsimon.vergauwen
07/18/2019, 12:58 PMfun <A> Kind<F, A>.remove(element: A,
monoid: Monoid<A>,
monoidK: MonoidK<F>,
AF: Applicative<F>): Kind<F, A> = AF.run {
foldLeft(AF.just(monoid.empty())) { foldable: Kind<F, A>, next: A ->
if (next == element) foldable
else monoidK.run { foldable.combineK(AF.just(next)) }
}
}
addamsson
07/18/2019, 12:59 PMApplicative
😞simon.vergauwen
07/18/2019, 12:59 PMMonoidK
is what you’re looking for, it’s meant to combine `F`s, * -> *
or constructors with a typehole.simon.vergauwen
07/18/2019, 12:59 PMmonoid.empty()
returns A
but the return type of our foldLeft
needs to be Kind<F, A>
so we need to lift it.addamsson
07/18/2019, 12:59 PMaddamsson
07/18/2019, 1:00 PMApplicative
providessimon.vergauwen
07/18/2019, 1:00 PMjust
which can (A) -> Kind<F, A>
addamsson
07/18/2019, 1:01 PMApplicative
works? I'm kinda lost heresimon.vergauwen
07/18/2019, 1:01 PMA
into F
, and then we can use MonoidK
to combine F
. You can overload this function in Traverse
and default supply the Applicative
instance.simon.vergauwen
07/18/2019, 1:01 PMaddamsson
07/18/2019, 1:01 PMsimon.vergauwen
07/18/2019, 1:02 PMfun <A> Kind<F, A>.remove(element: A,
monoid: Monoid<A>,
monoidK: MonoidK<F>,
AF: Applicative<F>): Kind<F, A> {
val emptyValue: A = monoid.empty()
val liftedEmpty: Kind<F, A> = AF.just(emptyValue)
return foldLeft(liftedEmpty) { foldable: Kind<F, A>, next: A ->
if (next == element) foldable
else monoidK.run {
val liftedNext = AF.just(next)
val newlyAccumulated = foldable.combineK(liftedNext)
newlyAccumulated
}
}
}
addamsson
07/18/2019, 1:03 PMjust
does is it wraps a value in a context?simon.vergauwen
07/18/2019, 1:03 PMfun <A> just(a: A): List<A> = listOf(a)
addamsson
07/18/2019, 1:03 PMsimon.vergauwen
07/18/2019, 1:03 PMaddamsson
07/18/2019, 1:03 PMOption.just(1)
simon.vergauwen
07/18/2019, 1:04 PMF
so we can accumulate the results in our collections. MonoidK.combineK
is append or +
for List
.addamsson
07/18/2019, 1:05 PMnext
values?addamsson
07/18/2019, 1:05 PMaddamsson
07/18/2019, 1:06 PMlistOf()
+ listOf(1)
+ listOf(3)
+ listOf(4)
?simon.vergauwen
07/18/2019, 1:06 PMsimon.vergauwen
07/18/2019, 1:07 PMaddamsson
07/18/2019, 1:07 PMaddamsson
07/18/2019, 1:08 PMsimon.vergauwen
07/18/2019, 1:09 PMfoldLeft
over our original Kind<F, A>
, and as an initial value we pass an “empty context”.
I thought the empty context could be constructed by using Monoid
+ Applicative
, but that’s inaccurate.
Monoid<Int>
returns 0
on empty
so wrapping it with Applicative#just
results in listOf(0)
instead of emptyList()
So what we want instead is simply MonoidK
, which it’s empty
returns emptyList()
.addamsson
07/18/2019, 1:09 PMmonoidK
has empty
simon.vergauwen
07/18/2019, 1:09 PMsimon.vergauwen
07/18/2019, 1:09 PMMonoid
either.simon.vergauwen
07/18/2019, 1:09 PMaddamsson
07/18/2019, 1:10 PMfun <A> Kind<F, A>.remove(element: A,
monoidK: MonoidK<F>,
AF: Applicative<F>): Kind<F, A> {
val emptyValue = monoidK.run {
empty<A>()
}
return foldLeft(emptyValue) { foldable: Kind<F, A>, next: A ->
if (next == element) foldable
else monoidK.run {
foldable.combineK(AF.just(next))
}
}
}
simon.vergauwen
07/18/2019, 1:10 PMaddamsson
07/18/2019, 1:11 PMsimon.vergauwen
07/18/2019, 1:11 PMval emptyValue = monoidK.run {
empty<A>()
}
Can simply be monoidK.empty<A>()
simon.vergauwen
07/18/2019, 1:13 PMemptyList() + listOf(1) + listOf(3) + listOf(4)
for ListK.foldable().run { listOf(1, 2, 3, 4).k().remove(2) }
simon.vergauwen
07/18/2019, 1:13 PMemptyList().combineK(listOf(1).combineK(listOf(3).combineK(listOf(4))))
=> monoidK.empty().combineK(just(1).combineK(just(3).combineK(just(4))))
simon.vergauwen
07/18/2019, 1:15 PMaddamsson
07/18/2019, 1:15 PMApplicative
is?addamsson
07/18/2019, 1:15 PMaddamsson
07/18/2019, 1:15 PMApplicative
is for yanking?simon.vergauwen
07/18/2019, 1:18 PMApplicative
😅 In Arrow it only adds the power to lift values into F
on top of Functor
.addamsson
07/18/2019, 1:18 PMaddamsson
07/18/2019, 1:19 PM"Should be able to remove from Foldable" {
val result = ListK.foldable().run { listOf(1, 2, 3, 4).k().remove(2, ListK.monoidK(), ListK.applicative()) }
result shouldBe listOf(1, 3, 4)
}
addamsson
07/18/2019, 1:19 PMaddamsson
07/18/2019, 1:19 PMjust
addamsson
07/18/2019, 1:20 PMEq
instead of ==
?simon.vergauwen
07/18/2019, 1:23 PMap
, which is not that useful in Kotlin and split off in Apply
. What is more interesting there is the derived functions which allow for combining N types wrapped in F
.
ListK.applicative(listOf(1, 2), listOf(3, 4)) { (a, b) -> Tuple2(a, b) }
//ListK(list=[Tuple2(a=1, b=3), Tuple2(a=1, b=4), Tuple2(a=2, b=3), Tuple2(a=2, b=4)])
simon.vergauwen
07/18/2019, 1:25 PMEq
instead of ==
but most of the tests that aren’t using Eq
have been there for a long time. We haven’t actively gone back to tests to rewrite them.addamsson
07/18/2019, 1:25 PMaddamsson
07/18/2019, 1:25 PMaddamsson
07/18/2019, 1:25 PMaddamsson
07/18/2019, 1:26 PMaddamsson
07/18/2019, 1:28 PMsimon.vergauwen
07/18/2019, 1:28 PMaddamsson
07/18/2019, 1:28 PMsimon.vergauwen
07/18/2019, 1:28 PMaddamsson
07/18/2019, 1:29 PMaddamsson
07/18/2019, 1:31 PMaddamsson
07/18/2019, 1:31 PMsimon.vergauwen
07/18/2019, 1:32 PMF
and turns them into a tuple.
fun <F, A, B> Applicative<F>.tupled(fa: Kind<F, A>, fb: Kind<F, B>) : Kind<F, Tuple2<A, B>> {
val ff: Kind<F, (B) -> Tuple2<A, B> = fa.map { a -> { b -> Tuple2(a, b) } }
return fb.ap(ff)
}
addamsson
07/18/2019, 1:32 PMlistOf(1, 2, 3, 4).k().remove(2, ListK.monoidK(), ListK.applicative())
simon.vergauwen
07/18/2019, 1:32 PMMonad
and flatMap
but that means it’ll always be sequential.addamsson
07/18/2019, 1:33 PMsimon.vergauwen
07/18/2019, 1:33 PMIO
we could write an Applicative
that uses parMapN
to combine 2 values in parallel.simon.vergauwen
07/18/2019, 1:34 PMaddamsson
07/18/2019, 1:34 PMaddamsson
07/18/2019, 1:34 PMsimon.vergauwen
07/18/2019, 1:34 PMFunctorFilter
alternativesimon.vergauwen
07/18/2019, 1:34 PMsimon.vergauwen
07/18/2019, 1:35 PMConcurrent
typeclass for a parApplicative()
instance.simon.vergauwen
07/18/2019, 1:35 PMApplicative
in a concurrent/parallel manner with guarantees about cancelation, error handling and resource safety etc.addamsson
07/18/2019, 1:36 PMApplicative
is capable of doing thatsimon.vergauwen
07/18/2019, 1:37 PMsimon.vergauwen
07/18/2019, 1:37 PMaddamsson
07/18/2019, 1:38 PMaddamsson
07/18/2019, 1:38 PMaddamsson
07/18/2019, 1:38 PMaddamsson
07/18/2019, 1:38 PMApply
has no kdocs 😢simon.vergauwen
07/18/2019, 1:39 PMaddamsson
07/18/2019, 1:40 PMfun <A, B> Kind<F, A>.ap(ff: Kind<F, (A) -> B>): Kind<F, B>
addamsson
07/18/2019, 1:40 PMsimon.vergauwen
07/18/2019, 1:40 PMaddamsson
07/18/2019, 1:40 PMApply
does is that it applies a function wrapped in a context to a value wrapped in a contextaddamsson
07/18/2019, 1:40 PMaddamsson
07/18/2019, 1:41 PMaddamsson
07/18/2019, 1:41 PMsimon.vergauwen
07/18/2019, 1:41 PMaddamsson
07/18/2019, 1:42 PMsimon.vergauwen
07/18/2019, 1:42 PMaddamsson
07/18/2019, 1:43 PMsimon.vergauwen
07/18/2019, 1:44 PMsimon.vergauwen
07/18/2019, 1:45 PMaddamsson
07/18/2019, 1:48 PMaddamsson
07/18/2019, 1:49 PMaddamsson
07/18/2019, 1:49 PMsimon.vergauwen
07/18/2019, 1:49 PMaddamsson
07/18/2019, 1:49 PMaddamsson
07/18/2019, 1:50 PMsimon.vergauwen
07/18/2019, 1:51 PMaddamsson
07/18/2019, 1:51 PMaddamsson
07/18/2019, 1:51 PMEq
into this implementation of remove
?simon.vergauwen
07/18/2019, 1:54 PMEq.any()
is ==
.
fun <A> Kind<F, A>.remove(element: A,
monoidK: MonoidK<F>,
AF: Applicative<F>,
eq: Eq<A> = Eq.any()): Kind<F, A> =
foldLeft(monoidK.empty()) { foldable: Kind<F, A>, next: A ->
if (eq.run { next.eqv(element) }) foldable
else monoidK.run { foldable.combineK(AF.just(next)) }
}
cc\ @raulraja we need KEEP-87 xDaddamsson
07/18/2019, 1:55 PMraulraja
07/18/2019, 1:58 PMraulraja
07/18/2019, 1:58 PMraulraja
07/18/2019, 1:58 PMval MetaComponentRegistrar.typeClasses: List<ExtensionPhase>
get() =
meta(
classOrObject(::isExtension) { ktClass ->
val typeClass = ktClass.typeClassName()
val typeArgs = ktClass.typeArgumentNames()
val factoryName = typeClass.decapitalize()
println("intercepted ${ktClass.name}")
listOf(
ktClass.text,
"fun $factoryName(): $typeClass<${typeArgs..","}> = TODO()"
)
},
IrGeneration { compilerContext, file, backendContext, bindingContext ->
file.transformChildren(object: IrElementTransformer<Unit> {
}, Unit)
}
)
raulraja
07/18/2019, 1:58 PMraulraja
07/18/2019, 1:59 PMtypeArgs..","
raulraja
07/18/2019, 2:00 PM","
can be any other delimitersimon.vergauwen
07/18/2019, 2:00 PMsimon.vergauwen
07/18/2019, 2:00 PMraulraja
07/18/2019, 2:00 PMsimon.vergauwen
07/18/2019, 2:00 PMsimon.vergauwen
07/18/2019, 2:00 PMsimon.vergauwen
07/18/2019, 2:00 PMraulraja
07/18/2019, 2:01 PMprivate operator fun <A> List<A>.rangeTo(s: String): String =
joinToString(s)
addamsson
07/18/2019, 2:15 PMaddamsson
07/18/2019, 2:15 PMfun <A> Kind<ForListK, A>.remove(element: A) = remove(element, ListK.monoidK(), ListK.applicative())
addamsson
07/18/2019, 2:15 PM@extension
interface ListKFoldable : Foldable<ForListK> {
override fun <A, B> Kind<ForListK, A>.foldLeft(b: B, f: (B, A) -> B): B =
fix().foldLeft(b, f)
override fun <A, B> Kind<ForListK, A>.foldRight(lb: Eval<B>, f: (A, Eval<B>) -> Eval<B>): Eval<B> =
fix().foldRight(lb, f)
override fun <A> Kind<ForListK, A>.isEmpty(): kotlin.Boolean =
fix().isEmpty()
fun <A> Kind<ForListK, A>.remove(element: A) = remove(element, ListK.monoidK(), ListK.applicative())
}
addamsson
07/18/2019, 2:16 PMremove
to Foldable
I'm going to augment all implementations with this to keep it ergonomicsimon.vergauwen
07/18/2019, 2:16 PMListKFoldable
interface.addamsson
07/18/2019, 2:17 PMaddamsson
07/18/2019, 2:17 PM"Should be able to remove from Foldable" {
val result = ListK.foldable().run { listOf(1, 2, 3, 4).k().remove(2) }
println(result)
result shouldBe listOf(1, 3, 4)
}
addamsson
07/18/2019, 2:18 PMFoldable
addamsson
07/18/2019, 2:18 PMaddamsson
07/18/2019, 2:19 PM@extension
will create an unboxed extension functionsimon.vergauwen
07/18/2019, 2:19 PMaddamsson
07/18/2019, 2:20 PMListK
then, thankssimon.vergauwen
07/18/2019, 2:20 PMaddamsson
07/18/2019, 2:21 PMremove
would make ListK
invariant 😞addamsson
07/18/2019, 2:21 PM<out A>
simon.vergauwen
07/18/2019, 2:22 PMListK
it is. The only way to walk around that problem now since Kotlin doesn’t allow for variance in functions.pakoito
07/18/2019, 2:23 PMpakoito
07/18/2019, 2:23 PMsimon.vergauwen
07/18/2019, 2:23 PMaddamsson
07/18/2019, 2:32 PMaddamsson
07/18/2019, 2:32 PMremove
function we imlpementedaddamsson
07/18/2019, 2:32 PMfun <A> ListK<A>.remove(element: A): ListK<A> = this.??? // can't find it
addamsson
07/18/2019, 2:33 PMfix()
doesn't help eitheraddamsson
07/18/2019, 2:33 PMListK
itselfaddamsson
07/18/2019, 2:34 PMFoldable
functions are implemented in ListKFoldable
?simon.vergauwen
07/18/2019, 2:34 PMimport arrow.core.extensions.listk.foldable.remove
simon.vergauwen
07/18/2019, 2:35 PMaddamsson
07/18/2019, 2:36 PMsimon.vergauwen
07/18/2019, 2:36 PMaddamsson
07/18/2019, 2:36 PMremove
for ListK
we could just use the wrapped `List`'s remove
addamsson
07/18/2019, 2:36 PMsimon.vergauwen
07/18/2019, 2:37 PMaddamsson
07/18/2019, 2:37 PM"Should be able to remove from Foldable" {
val result = ListK.foldable()
.run { listOf(1, 2, 3, 4).k() }
.remove(2, ListK.monoidK(), ListK.applicative())
result shouldBe listOf(1, 3, 4)
}
addamsson
07/18/2019, 2:38 PMFoldable
thoughsimon.vergauwen
07/18/2019, 2:39 PMarrow-test
they’re implemented as an abstract test suite. Called FoldableLaws.laws(...)
addamsson
07/18/2019, 2:39 PMsimon.vergauwen
07/18/2019, 2:39 PMaddamsson
07/18/2019, 2:40 PMaddamsson
07/18/2019, 2:40 PMaddamsson
07/18/2019, 2:51 PMPersistentMap
implementation?addamsson
07/18/2019, 2:51 PM/**
* A [PersistentMap] is an immutable [Map] which implements structural sharing.
*/
@higherkind
data class PersistentMap<K, V>(private val map: Map<K, V>) : PersistentMapOf<K, V> {
val isEmpty: Boolean = map.isEmpty()
val size: Int = map.size
operator fun get(key: K): Option<V> = Option.fromNullable(map[key])
fun getOrElse(key: K, defaultValue: V): V = map.getOrElse(key) { defaultValue }
fun containsKey(key: K): Boolean = map.containsKey(key)
fun put(key: K, value: V): PersistentMap<K, V> {
TODO()
}
fun remove(key: K): PersistentMap<K, V> {
TODO()
}
}
pakoito
07/18/2019, 2:54 PMpakoito
07/18/2019, 2:54 PMaddamsson
07/18/2019, 3:05 PMaddamsson
07/18/2019, 3:05 PM/**
* A [PersistentMap] is an immutable [Map] which implements structural sharing.
*/
@higherkind
data class PersistentMap<K, V>(private val map: HashArrayMappedTrie<K, V>) : PersistentMapOf<K, V> {
val isEmpty: Boolean = map.isEmpty
val size: Int = map.size
operator fun get(key: K): Option<V> = map[key]
fun containsKey(key: K): Boolean = map.containsKey(key)
fun put(key: K, value: V): PersistentMap<K, V> {
return PersistentMap(map.put(key, value))
}
fun remove(key: K): PersistentMap<K, V> {
return PersistentMap(map.remove(key))
}
}
addamsson
07/18/2019, 3:08 PMaddamsson
07/18/2019, 3:08 PMpakoito
07/18/2019, 3:55 PMaddamsson
07/18/2019, 4:18 PMpakoito
07/18/2019, 4:20 PMaddamsson
07/18/2019, 4:22 PMaddamsson
07/18/2019, 4:22 PMaddamsson
07/18/2019, 5:19 PMaddamsson
07/18/2019, 5:20 PMMapK
are necessary because we don't have KEEP-87 yet, right?addamsson
07/18/2019, 5:20 PMPersistentMapK
simon.vergauwen
07/18/2019, 5:22 PMKind
.simon.vergauwen
07/18/2019, 5:23 PMPersistentMap
addamsson
07/18/2019, 5:39 PMaddamsson
07/18/2019, 5:39 PMaddamsson
07/18/2019, 5:40 PMmapk.kt
addamsson
07/18/2019, 5:41 PMaddamsson
07/18/2019, 5:43 PMPersistentMapK
a Foldable
apart from this?addamsson
07/18/2019, 5:43 PM@extension
interface MapKFoldable<K> : Foldable<PersistentMapKPartialOf<K>>
addamsson
07/18/2019, 5:49 PMsimon.vergauwen
07/18/2019, 5:54 PMaddamsson
07/18/2019, 5:56 PMFunctor
?addamsson
07/18/2019, 5:56 PM@extension
@undocumented
interface PersistentMapKFunctor<K> : Functor<PersistentMapKPartialOf<K>>
simon.vergauwen
07/18/2019, 5:57 PMPersistentMapKFunctor
becomes an interface with no abstract functions.addamsson
07/18/2019, 5:58 PMsimon.vergauwen
07/18/2019, 5:58 PMFunctor
that's only map
if I'm not mistaken.addamsson
07/18/2019, 5:58 PMmap
on my PersistentMapK<Int, Int>()
simon.vergauwen
07/18/2019, 5:58 PMaddamsson
07/18/2019, 5:58 PM@extension
@undocumented
interface PersistentMapKFunctor<K> : Functor<PersistentMapKPartialOf<K>>
addamsson
07/18/2019, 5:58 PMmapk.kt
addamsson
07/18/2019, 5:59 PMsimon.vergauwen
07/18/2019, 6:00 PM@extension
@undocumented
interface PersistentMapKFunctor<K> : Functor<PersistentMapKPartialOf<K>> {
override fun <A, B> PersistentMapKOf<A>.map(f: (A) -> B): PersistentMapK<B> =
fix().map(f)
}
Now that you’ve implemented all abstract methods of interface Functor<F>
, we can no generate fun <K> PersistentMapK.Companion.functor(): Functor<PersistentMapKPartialOf<K>> = object : PersistentMapKFunctor<K> { }
raulraja
07/18/2019, 6:00 PMraulraja
07/18/2019, 6:01 PMaddamsson
07/18/2019, 6:01 PMsimon.vergauwen
07/18/2019, 6:01 PMFunctor
provides with faster implementations, but that’s optional.simon.vergauwen
07/18/2019, 6:02 PMmap
on PersistentMapK
?addamsson
07/18/2019, 6:02 PMaddamsson
07/18/2019, 6:02 PMraulraja
07/18/2019, 6:05 PMraulraja
07/18/2019, 6:05 PMraulraja
07/18/2019, 6:06 PMsimon.vergauwen
07/18/2019, 6:06 PMfix
. I.e. fix().map(f)
.
So if we look at Option
it looks like this with only the Functor impl.
@higherkind sealed class Option<out A> : OptionOf<A> {
object None: Option<Nothing>()
data class Just<A>(val a: A): Option<A>()
fun <B> map(f: (A) -> B): Option<B> = ...
}
interface OptionFunctor : Functor<ForOption> {
fun <A, B> OptionOf<A>.map(f: (A) -> B): Option<B> =
fix() //returns Option<A>
.map(f)
}
addamsson
07/18/2019, 6:07 PMMapK
simon.vergauwen
07/18/2019, 6:08 PMaddamsson
07/18/2019, 6:08 PMPersistentMapKOf
simon.vergauwen
07/18/2019, 6:08 PMPersistentMapKOf
is simply typealias PersistentMapKOf<K, V> = Kind2<ForPersistentMapK, K, V>
simon.vergauwen
07/18/2019, 6:10 PMPersistentMapK<K, V>
is equal to PersistentMapKOf<K, V>
and additionally we can tell the compiler that PersistentMapK
has all the functions that are implemented by the typeclasses for ForPersistentMapK
.addamsson
07/18/2019, 6:10 PMaddamsson
07/18/2019, 6:10 PMsimon.vergauwen
07/18/2019, 6:10 PMaddamsson
07/18/2019, 6:11 PMaddamsson
07/18/2019, 6:11 PMsimon.vergauwen
07/18/2019, 6:11 PMaddamsson
07/18/2019, 6:11 PMaddamsson
07/18/2019, 6:12 PMmap
like this:addamsson
07/18/2019, 6:12 PM@extension
@undocumented
interface PersistentMapKFunctor<K> : Functor<PersistentMapKPartialOf<K>> {
override fun <A, B> Kind<PersistentMapKPartialOf<K>, A>.map(f: (A) -> B): Kind<PersistentMapKPartialOf<K>, B> {
TODO("not implemented")
}
}
simon.vergauwen
07/18/2019, 6:12 PMFunctor
addamsson
07/18/2019, 6:12 PMPersistentMapK
is already a kind and kapt can work its magicaddamsson
07/18/2019, 6:12 PMaddamsson
07/18/2019, 6:22 PM> Task :arrow-persistent-data-structures:kaptKotlin FAILED
e: error: Arrow's annotations can only be used on Kotlin classes. Not valid for error.NonExistentClass
after each build?addamsson
07/18/2019, 6:23 PMPersistentMapKOf
from PersistentMapK
then rebuild then re-add itsimon.vergauwen
07/18/2019, 6:23 PM@higherkind
and @extension
in the same module?simon.vergauwen
07/18/2019, 6:23 PM@higherkind
boilerplate in the module for now.addamsson
07/18/2019, 6:24 PMaddamsson
07/18/2019, 6:24 PMaddamsson
07/18/2019, 6:27 PMcompanion object
to PersistentMapK
addamsson
07/18/2019, 6:27 PMaddamsson
07/18/2019, 6:27 PMaddamsson
07/18/2019, 7:11 PMremove
is not going to work since Foldable
folds the valuesaddamsson
07/18/2019, 7:12 PMremove
works with the key
, not the value 😞addamsson
07/18/2019, 7:13 PMFoldable
the wrong wayaddamsson
07/18/2019, 7:13 PMsimon.vergauwen
07/18/2019, 7:14 PMOptics
.simon.vergauwen
07/18/2019, 7:15 PMFoldable
wrong. We don't know the type of the key
inside Foldable
.simon.vergauwen
07/18/2019, 7:17 PMsimon.vergauwen
07/18/2019, 7:19 PMaddamsson
07/18/2019, 7:20 PMaddamsson
07/18/2019, 7:20 PMkey
in order to implement an efficient remove
operationsimon.vergauwen
07/18/2019, 7:20 PMkey
for FunctorFilter
.addamsson
07/18/2019, 7:20 PMremove
function in PersistentMap
addamsson
07/18/2019, 7:20 PMaddamsson
07/18/2019, 7:21 PMsimon.vergauwen
07/18/2019, 7:21 PMIndexedFoldable
or IndexedFunctorFilter
addamsson
07/18/2019, 7:21 PMremove(element)
function anywaysimon.vergauwen
07/18/2019, 7:22 PMsimon.vergauwen
07/18/2019, 7:25 PMsimon.vergauwen
07/18/2019, 7:26 PMaddamsson
07/18/2019, 7:27 PMsimon.vergauwen
07/18/2019, 7:30 PMaddamsson
07/18/2019, 7:30 PMaddamsson
07/18/2019, 7:32 PMaddamsson
07/18/2019, 7:43 PMaddamsson
07/18/2019, 7:43 PMMissing newline before ")"
addamsson
07/18/2019, 7:43 PM)
at the end of the line (just like in Clojure)addamsson
07/18/2019, 7:54 PMsimon.vergauwen
07/18/2019, 7:56 PMsimon.vergauwen
07/18/2019, 7:57 PMaddamsson
07/18/2019, 8:09 PMaddamsson
07/18/2019, 8:09 PMaddamsson
07/18/2019, 8:09 PMaddamsson
07/18/2019, 8:09 PMaddamsson
07/18/2019, 8:10 PMaddamsson
07/19/2019, 11:12 AMImran/Malic
07/19/2019, 11:52 AMfun <A> Kind<F, A>.remove(element: A,
monoidK: MonoidK<F>,
AF: Applicative<F>): Kind<F, A> {
Imran/Malic
07/19/2019, 11:53 AMsimon.vergauwen
07/19/2019, 11:56 AM./gradlew ktlintFormat
should fix all style isssues, and the onces it cannot like *
imports will get linked in the console.addamsson
07/19/2019, 12:54 PMsimon.vergauwen
07/19/2019, 12:54 PMaddamsson
07/19/2019, 1:36 PMaddamsson
07/19/2019, 1:36 PMTraverse
typeclass, but we discussed Foldable
with @simon.vergauwensimon.vergauwen
07/19/2019, 1:48 PMTraverse
inherits from Foldable
and Functor
and is a very popular and powerful typeclass to do operations.
fun getUserById(id: Int): IO<User> = ...
val operations: List<IO<User>> = listOf(1, 2, 3).k().map(::getUserById)
val sequenced: IO<List<User>> = operations.sequence(IO.applicative())
val traversed: IO<List<User>> = listOf(1, 2, 3).k().traverse(IO.applicative()) { id -> getUserById(id) }
Having List<IO<User>>
is useless to work with so you need to be able to swap the order of the contexts.simon.vergauwen
07/19/2019, 1:49 PMIO.parApplicative()
which we discussed earlier will automatically make this work in parallel. Which is exactly what we I did in that PR I shared, parTraverse
is just an alias for traverse
with parApplicative()
.addamsson
07/19/2019, 2:06 PMIO
?addamsson
07/19/2019, 2:07 PMTraverse
addamsson
07/19/2019, 2:08 PMsimon.vergauwen
07/19/2019, 2:08 PMio.reactivex.Single
, reactor.Mono
which are both pure and fairly principled. You can also see it as a FP version of kotlinx.coroutines.Deferred
, or Scala Future.addamsson
07/19/2019, 2:08 PMsimon.vergauwen
07/19/2019, 2:08 PMIO
uses coroutines for threading under the hood yesaddamsson
07/19/2019, 2:08 PMIO
or Traverse
?Imran/Malic
07/19/2019, 2:08 PMaddamsson
07/19/2019, 2:09 PMIO
~ Deferred
or Traverse
~ Deferred
?simon.vergauwen
07/19/2019, 2:09 PMIO
~ Deferred
Imran/Malic
07/19/2019, 2:09 PMaddamsson
07/19/2019, 2:09 PMImran/Malic
07/19/2019, 2:10 PMImran/Malic
07/19/2019, 2:10 PMaddamsson
07/19/2019, 2:10 PM0
Scala knowledgesimon.vergauwen
07/19/2019, 2:10 PMaddamsson
07/19/2019, 2:10 PMsimon.vergauwen
07/19/2019, 2:11 PMaddamsson
07/19/2019, 2:11 PMsimon.vergauwen
07/19/2019, 2:12 PMF
and you want to run functions that return G
. So in our example our original context was List
and we wanted to run functions that return IO
.
But a simpler example maybe.
fun getOptionalUser(id: Int): Option<User> = ..
listOf(1, 2, 3).k().traverse { id -> getOptionalUser(id) }
simon.vergauwen
07/19/2019, 2:14 PMList<Option<User>>
but lets say I am not interested in having empty values (None
) in my list.
So I want to short-circuit just like `map`/`flatMap` for Option
and have an Option<List<User>>
which either contains all users or None
.addamsson
07/19/2019, 2:14 PMlistOf(1, 2, 3).k().traverse { id -> getOptionalUser(id) }
return?simon.vergauwen
07/19/2019, 2:14 PMOption<List<User>>
addamsson
07/19/2019, 2:15 PMFunctor
) but also folds Foldable
?simon.vergauwen
07/19/2019, 2:16 PMinterface Traverse<F> : Functor<F>, Foldable<F>
addamsson
07/19/2019, 2:16 PMaddamsson
07/19/2019, 2:16 PMApplicative
?addamsson
07/19/2019, 2:16 PMApply
simon.vergauwen
07/19/2019, 2:17 PMApplicative<G>
so that you can use map2
to combine 2 G
elements.addamsson
07/19/2019, 2:17 PMsimon.vergauwen
07/19/2019, 2:19 PMfun Kind<G, Kind<F, A>>.sequence(AF: Applicative<F>): Kind<F, Kind<G, A>> = traverse(AF, :identity)
val listOfOptions: List<Option<Int>> = listOf(1.some(), 2.some())
listOfOptions.sequence() //Some([1, 2])
listOf(1.some(), None).sequence() // None
simon.vergauwen
07/19/2019, 2:20 PMlistOf(1, 2).map { Some(it) }.sequence()
is the same as listOf(1, 2).traverse { Some(it) }
addamsson
07/19/2019, 2:23 PMaddamsson
07/19/2019, 2:23 PMaddamsson
07/19/2019, 6:06 PMaddamsson
07/19/2019, 9:44 PMaddamsson
07/19/2019, 10:20 PMaddamsson
07/19/2019, 10:20 PMsimon.vergauwen
07/19/2019, 10:43 PMraulraja
07/23/2019, 8:58 AMsimon.vergauwen
07/23/2019, 8:59 AMremove(a).find { a } == false
but currently we haven't defined any yetraulraja
07/23/2019, 9:00 AMraulraja
07/23/2019, 9:01 AMraulraja
07/23/2019, 9:02 AMraulraja
07/23/2019, 9:02 AMImran/Malic
07/23/2019, 9:18 AM