this n*m seems to be the exact thing bartos millei...
# arrow
j
this n*m seems to be the exact thing bartos milleiw (sp?) addresses in his very first lecture.
r
Arrow provides abstraction for Foldable, Functor and many other abstractions that you have to implement over your datatypes if you want to benefit from them, but the user is responsible to provide extension instances for the data type they are creating . I'm not sure arrow provides a straight solution to your issue
Also let's try to keep long conversations in threads so other users can just focus on those issues they care about, thanks 🙂
😀 1
j
how might one abstract the commonalities of List and Array as Functor?
im looking, and it appears ListK is written to abstract lists as functors, but it seems like these(arrays, lists) should be compatible as immutable 1-d structures
r
You can proof a container is a Functor of you can implement it with map on an instance like ListK does in it's Functor instances
Or it may not be Functor but foldable
There are a few instances for maps there as well in arrow
And you can create instances a la carte if your datastructure by definition can form a valid Functor or foldable or whatever
That unlocks new apis in your type that the typeclasses project once you complete one of their main methods in your implementation
For example Functor.map gives you Functor.lift and others for free
Also in datastructures map is frequently a fold
Since most datastructures are foldable and tree like ADTs we can derive a lot of common known patterns for it
That is what arrow core does
I'd you look at the impls of all data types in arrow they are the same
j
I'm just trying to associate how in c++, a functor can be one of many unary or binary functions that exist to terminate an iterator which goes from one end of a address space to the other. i should be able to rewrite the order of a list identically using a numeric index against either of the list or array targets. there's nothing familiar about the Functor documentation I'm reading here
r
Now the question is, what data type are you dealing with and what can arrow give you for free if you proof structure via extension
Functor in arrow is the same as a Functor in Haskell
What you describe is foreign to me and unrelated to the category theory concept of Functor
What you describe sounds more like abstracting over arity
j
which really sucks because we have the same wiords in two entirely unsimilar dictionaries
r
In Kotlin that is not possible because there is no notion of peano numbers, nats, hlist or even generalized product types
Which what you need in a compiler to abstract over function arity without creating 22+ versions of the same impl
Arrow suffers that too
Out tuple encoding is like that
Boilerplate
j
my actual source code has these 6 operators to allow reindexing an ordered set.
Copy code
@JvmName("getVA")
inline operator fun <reified T> List<T>.get(vararg index: Int) = get(index)

inline operator fun <reified T> List<T>.get(index: IntArray) = List(index.size) { i: Int -> this[index[i]] }

@JvmName("getVA")
inline operator fun <reified T> Sequence<T>.get(vararg index: Int) = get(index)

inline operator fun <reified T> Sequence<T>.get(index: IntArray) = this.toList()[index].asSequence()

@JvmName("getVA")
inline operator fun <reified T> Array<T>.get(vararg index: Int) = get(index)

inline operator fun <reified T> Array<T>.get(index: IntArray) = Array(index.size) { i: Int -> this[index[i]] }
r
But in meta eventually we will have polyfunctions that have arbitrary typed arity
j
what is the Arrow higher kind expression of these 6 ? can it be brought down to fewer?
r
What are those return types?
j
In All Cases these are new versinos of the old container
F
well , I hope F and I'm not reading the example wrong
r
Then it's Kind<F, Int> and probably all those constrains can be satisfied for Foldable
Where index may be also Kind F Int
j
these all take the vararg and reassign new seq/array/list order from existing elements
and the spread operator is removed by the second overload
because huge leak
r
Why are you not using SortedSet?
j
the order might be array[1,2,1,1,0,1]
r
Which can injest, diff etc all collections and Iterables including arrays
Then it's and indexed list or Vector like scalas
Which give you constant time effectively in all ops
Not sure if there is an impl for that in Kotlin
But that will allow you to have indexed access and duplicates
j
the 6 methods gives me like50% of pandas functionality for .. 6 lines plus lambdas
Once you have a vector like you can implement all.arrow.instances and get all the functionality of the type classes
j
so i should port it?
r
That unlocks comprehensions and Fx in arrow so you can compute imperatively over the data structure
I would play with it in Scala and see if it fits your use case and if it does definetly port it and contribute it to arrow
This is a much needed structure in arrow and Kotlin imo unless there is already one used out there
If you port it please consider contributing to arrow and we will help maintaing it if you are interested
j
🤯
this looks like a throwback of kotlin, the language features and the cats methods are really overlapping here. plus that's a lot of boilerplate in order to arrive at the 6 lines of effective emulation.
i was trying to port .get() to Functor but the end result is 4 arrow-kt videos in 4 tabs and a lot of docs and a ton of open arrow-kt source files open. I think you have clarified a lot of the missing picture for me.
i get foldable and right left concepts, i just rarely need these for matrix operations
i am doing the vector abstraction through Flows presently, with efficient postponed execution until keys are reified and alter the matrix geometries.
the necessary solution affords n*m IO attributes (fixed,varaible width)(text,binary)(row,col sequential)(serialize,deser) if there is an Arrow type abstraction to avoid or encapsulate the cartesian of these orthogonals, i might learn something
I am otherwise at the mercy of maintaining 2x2x2x2-1 conversion functions for 8+ primitive types
I initially tested out using Either but apparently i mis-interpret right and left promotion in this aspect
the underlying NIO api is an iterator with reversible IO features to memory and disk as are row and column storage access performance of particular interest.
I can use Right and Left types to create the entire serialization library as one tuple. What I understand is that Arrow and Haskell foundations view Right and Left as fail/succeed
in my code I have Vector-like kotlin constant-time code written mostly to arrays, but also applicable to •
Pair<()->Int/**size*/ ,(Int)->An?y>>
•
Sequence  O(N2)
•
Flow up to O(N^2)
•
List
operations:
combine
,
pure
,
get
,
reorder
noting that kotlin provides a patchwork of manually maintained keyboard practice code.
r
combine is Semigroup and you probably have monoid empty for your values. pure is in Applicative as just and get/reorder should be all derivatives of Fold/Traverse
If it’s something like a Vector or a list it would also have monad in which you can use comprehensions to compute, also in the arrow docs
j
i am happy to contribute the progress i have to date that just seem like bondo between stdlib routines i'd like to see
r
You will quickly discover using flow you can compute imperatively over the stream and it becomes a chain of nested flatMaps
there is where comprehensions work
if your data type can implement flatMap most likely can have imperative syntax like that
j
sure, flow and sequence blocks yield values. arrays and pairs composing linear access and lists only share
<Any>
kotlin types so this gets into the generative tagging and annotation beyond my immediate depth to backfill the boilerplate
flows appear to have significantly more overhead than sequences. it seems you can stack terminal operations all day long but escape analysis doesn't know what's going on so your graphs may yield very large side effects.they are also painfully forward-only with no handle objects that you can choose not to emit an index. you have to drop it on floor