Good Morning! :slightly_smiling_face: Would some...
# arrow
a
Good Morning! πŸ™‚ Would somebody please be so kind to explain to me what the idea is behind Invariant's imap function? I'm more than a little bit puzzled about it's sginature. Thanks!
s
Good morning πŸ™‚ I think this document from Typelevel Cats explains it very nicely. I don't think it's commonly used in Kotlin atm, but it's useful nevertheless. https://typelevel.org/cats/typeclasses/invariant.html TL;DR if you have some logic for type
Date
but you need to work with
Long
but you know how to map
Date -> Long
and map back
Long -> Date
then you can use
Invariant
to apply that logic over
Date
. Given that they're nested inside
Either
, or
Validated
etc.
a
Hello Simon! Oi, thank you! πŸ™‚ That raises a question: How much concepts has Arrow borrowed from Cats/Kittens? Best regards
Alex
s
Well, Arrow already has quite a history πŸ˜„ It originally started in a study group that was porting functional concepts from Scala to Kotlin. So at that point I'd say almost 100%. That was about 3,5-4 years ago I believe, I wasn't involved at the time. However in the last 2 years, and especially the last year we've been putting in a lot of work to make everything make more sense in Kotlin. We've worked to port all principles and benefits from
IO
into
suspend
with Arrow Fx Coroutines. We're removing things that don't make a lot of sense, like
Option
which is only necessary in certain generic code but not so relevant in user code, etc. But Cats was originally inspired from ScalaZ to make more sense in Scala, which was a port from the Haskell standard library. All these concepts in functional programming are the same, but it's a balance of what works best in certain languages/VMs etc.
a
Great! So I can turn not only to Hackage but also to the Cats documentation for reference. Thank you!
πŸ‘πŸΌ 1
t
@simon.vergauwen Could you please share how you would write the example from Cats in Arrow.
I mean this one
Copy code
def longToDate: Long => Date = new Date(_)
def dateToLong: Date => Long = _.getTime

implicit val semigroupDate: Semigroup[Date] =
  Semigroup[Long].imap(longToDate)(dateToLong)

val today: Date = longToDate(1449088684104l)
val timeLeft: Date = longToDate(1900918893l)
s
Here is an
Invariant
instance for
Monoid
, it seems there isn't one for
Semigroup
. Sadly it requires higher kinds to do this. https://github.com/arrow-kt/arrow-core/blob/master/arrow-core/src/main/kotlin/arrow/core/extensions/MonoidInvariant.kt
This allows you to call
Monoid.long().imap(longToDate, dateToLong)
and get back
Monoid<Date>
.
t
There seems to be no
ForSemigroup
that threw me off.
☝️ 2
Great, thanks. πŸ‘
πŸ‘ 2
a
Mhm. Mhmhmhm. So I could use Invariant to define a bijection?
s
A bijection within a context
F
a
In the example above what would the context be I wonder...?
s
F
for
Invariant
there is
Monoid
, but it could just as well be
Either
or etc
Any higher kinded type, otherwise you're probably looking for
Iso
a
Okay. Thank you Simon! πŸ™‚
πŸ‘ 1