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 PMIterableaddamsson
07/14/2019, 2:10 PMOption which is an empty Iterable if it is None and an Iterable with 1 element if it is Someaddamsson
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 PMarrowaddamsson
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 PMelementaddamsson
07/15/2019, 5:55 PMaddamsson
07/15/2019, 5:58 PMFunctorFilterraulraja
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 filteraddamsson
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 filteraddamsson
07/15/2019, 6:02 PMaddamsson
07/15/2019, 6:03 PMFunctorFilter and Eqaddamsson
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 PersistentMapaddamsson
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 thisaddamsson
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 PMFunctorFilteraddamsson
07/15/2019, 6:22 PMEq should be used instead of ==addamsson
07/15/2019, 6:22 PMEqaddamsson
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 PMMapKaddamsson
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 FunctorFilteraddamsson
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 AMMapKaddamsson
07/18/2019, 9:22 AMMap in our PersistentMapaddamsson
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 PMFoldTestaddamsson
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 composeaddamsson
07/18/2019, 12:40 PMidentityaddamsson
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 emptysimon.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 PMjustaddamsson
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 PMFoldableaddamsson
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 itaddamsson
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.removesimon.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 removeaddamsson
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 PMPersistentMapKsimon.vergauwen
07/18/2019, 5:22 PMKind.simon.vergauwen
07/18/2019, 5:23 PMPersistentMapaddamsson
07/18/2019, 5:39 PMaddamsson
07/18/2019, 5:39 PMaddamsson
07/18/2019, 5:40 PMmapk.ktaddamsson
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.ktaddamsson
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 PMMapKsimon.vergauwen
07/18/2019, 6:08 PMaddamsson
07/18/2019, 6:08 PMPersistentMapKOfsimon.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 PMFunctoraddamsson
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 PersistentMapKaddamsson
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 PersistentMapaddamsson
07/18/2019, 7:20 PMaddamsson
07/18/2019, 7:21 PMsimon.vergauwen
07/18/2019, 7:21 PMIndexedFoldable or IndexedFunctorFilteraddamsson
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 PMTraverseaddamsson
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 ~ DeferredImran/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 PMApplysimon.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() // Nonesimon.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