<@U0RM4EPC7> I've checked the typeclasses and I th...
# arrow-contributors
a
@simon.vergauwen I've checked the typeclasses and I think I can do
PersistentCollection
+
PersistentMap
only with
Semigroup
,
Monoid
,
Foldable
,
Functor
and
FunctorFilter
. There is one question though: Implementing removal with
FunctorFilter
isn't going to be ineffective? I mean it is
O(n)
vs
O(log n)
or even
O(1)
in some of the cases. Is there a typeclass for explicit removal instead of filtering?
There is also an interesting question: do we even want to differentiate between
PersistentCollection
and
PersistentMap
?
In Clojure for example maps are also collections (of paris)
it would make sense to just have 1 common ancestor for all persistent collections and go from there
s
Yes, you can do the same.
This works based on partial type application. Do you know how that works?
a
I'm not sure
is it similar to partial function application?
I'm a FP newbie
s
It’s similar yes. A simple example.
List<A>
takes 1 type parameter to become a real type. i.e. List + Int = List<Int>. When we take
Functor
it takes a type that takes 1 type parameter, or it takes a Higher kind type of rank 1 (* -> *). This is so we can define
fun <A, B> List<B>.map(f: (A) -> B): List<B>
, here we require 2 generic types in the function and apply them to the type of Functor.
Functor<ForList>
This happens by doing
Kind<ForList, A>
where you can apply a type to
ForList
using the
Kind
interface.
However
Map<A, B>
takes 2 parameters, so we need to somehow turn it into a type that only takes 1 parameter so we can use it with
Functor
. Again you can do this with
Kind
so let’s say we’d want to use
String
as
A
or key in the map, we do
Kind<ForMap, String>
. This still takes another kind parameter before we can consider the type a
Map
.
Hope that makes some sense 😅
Is there a typeclass for explicit removal instead of filtering?
I had to double check but I am not sure if we currently have something like that. It’s a pattern available in
Optics
by using
At
. https://github.com/arrow-kt/arrow/blob/master/modules/optics/arrow-optics/src/main/kotlin/arrow/optics/typeclasses/At.kt#L128
a
I checked
At
it is not good, as it only modifies an element.
We need a
remove
operation
So how would
ForMap
look like?
do I have to do something extra to implement
Monoid<PersistentCollection<E>>
,
Foldable<E>
,
Functor<E>
and
FunctorFilter<E>
?
apart from doing this:
Copy code
interface PersistentCollection<E> : Monoid<PersistentCollection<E>>, Foldable<E>, Functor<E>, FunctorFilter<E>
I'm not sure how to return a
Kind
or an
Eval
r
you would not inherit those interfaces but provide bridge extensions for them
what is the type signature of
remove
applied to a concrete type?
a
detailed here, right?
fun remove(element: E): PersistentCollection<E>
or rather
PersistentCollection<E>.fun remove(element: E): PersistentCollection<E>
so you have a
remove
function for each collection type
(
Set
and
List
for now)
oh wait a second
is this what
Kind
is used for?
Kind<ForPeristentCollection, E>
?
although it is not very useful to talk about
PersistentCollection
since all operations should return either a
PersistentSet
or a
PersistentList
not a collection
that would just replicate the problem the stdlib has
s
That's why you need
ForPersistentSet
and
ForPersistentList
, then you can apply them to a type parameter using
interface Kind<F, A>
. This results in
typealias PersistentSetOf<A> = Kind<ForPersistentSet, A>
, and then you should inheret from the typealias
@higherkind interface PersistentSet<A> : PersistentSetOf<A>
. The annotation will generate all the boilerplate for you so you only have to inherit from the typealias and add the annotation.
To go from
PersistentSetOf<A>
to
PersistentSet<A>
you have to call
fix()
because the compiler currently doesn't understand higher kinded types so we have to write some boilerplate. This small piece of boilerplate will disappear when we release the compiler plugin for kinds.
You can implement the
Functor
,
object PersistentSetFunctor : Functor<ForPersistentSet> {...}
. When we fill in all the generics for map it looks like this
fun <A> PersistentSetOf<A>.map(f: (A) -> B): PersistentSet<A>
.
a
Given that I get most of the functionality from the aforementioned typeclasses
there is really no point in having a
PersistentCollection
at all
s
Similarly you can do the same with
ForPersistentList
and
PersistentMapPartialOf<String>
.
a
thanks @simon.vergauwen
i've just found the relevant docs!
s
You're very welcome 👍
a
designing data structures without inheritance is kinda new for me 😄
s
Sounds like a fun time :D
a
it is
i'm almost done with HAMT
🎉 2
😱 1
although there is already a better version, CHAMP.
there is one problem though
if I'm using the Arrow setup I'll have to replicate it in my project
which seems tedious
do you have any suggestions, @simon.vergauwen?
r
if I’m using the Arrow setup I’ll have to replicate it in my project
Can you elaborate in what you mean by that?
a
The original concept was that I'll implement the VAVR port in my own project
and backport it to Arrow
this is because of the MPP requirement
@simon.vergauwen suggested that I should copy the necessary interfaces from Arrow to my project
but given the kapt magic Arrow does this might not be an option here
btw HAMT is working!
I just need to test the hell out of it
r
Can't you just depend on arrow core and add the arrow meta kapt plugin on your project? Then if you wish to contribute it to arrow we can just migrate the repo and rename it to arrow-collections or whatever it makes sense
Should be as easy as adding the arrow core dep for 0.9.1-SAPSHOT and the Gradle plugin for arrow meta
a
No, I can't my project is MPP
99% of the code is in common modules
That's why I asked whether the core interfaces are MPP in Arrow
then it turned out that this is not how you use Arrow in the first place so I think we're at an impasse right now
How can I help with the MPP effort btw?