what's the equivalent of / replacement for `Writer...
# arrow
m
what's the equivalent of / replacement for
WriterT
these days? I want to use Either-like and Writer-like effects together
👍 1
s
cc: @simon.vergauwen / @raulraja I am curious about your rationale here.
r
@Mickey Donaghy @Satyam Agarwal Do you have a small example program expressed in terms of WriterT that shows what you are trying to achieve? We no longer support this type of effect with an explicit data type but we may have an opinion on how to express the same program in Kotlin with or without Arrow.
s
I don’t. I am actually unfamiliar about the writerT monad, that’s why I tagged you so that I could fish out some examples, that’ll help me understand that. ReaderT and writeT like you said are long gone from the library, so definitely examples would not be abstract, thus giving me insight on how to use writerT. I have used reader from arrow before, so I know atleast how that works.
j
We could easily support writer effects and I think thats quite useful. Writing out any sort of data is useful imo. Either way the effect can be implemented as such:
Copy code
interface WriterEffect<W> {
  fun tell(w: W): Unit
}

object writer {
  inline fun <W, A> strict(wMonoid: Monoid<W>, act: WriterEffect<W>.() -> A): Pair<A, W> = ...
}
Other interpretations are possible:
Copy code
fun writer.bytes(sink: Sink<Bytes>, act: WriterEffect<Bytes>.() -> A): A
For arrow we'd just need to interface plus a pure strict implementation. Why is this useful? Well you can implement writing out data using writers that simply write on tell rather than accumulate and in tests run the same functions with a pure strict writer and have an easy test result to compare. In general writing data is an effect that makes sense to model outside of IO to abstract it away if need be (such as in tests, refractoring etc) and implementing this is rather easy as well.
I am however against adding
pass/listen
to the api as those are harder to get right in kotlin and don't add too much value imo
r
to add to what Jannis said, while it may be useful to many I don’t really mind the concrete version in most cases where writer is not even mentioned and you just deal with the Pairs and suspend
Here is an example from cats using writer https://typelevel.org/cats/datatypes/writert.html
This in Kotlin I would express as
That is if it was translated very close to the scala example but in my opinion for most use cases we know what we are logging and returning. Using a combination of suspend and pair covers most use cases and examples I’ve found for Writer
m
I wanted to make it harder to accidentally drop one of the pairs
just for things like audit log where I don't really want to be explicitly plumbing it through my business logic, but it's important that it doesn't get lost
r
@simon.vergauwen is here with me and he does not have his computer but he wrote this as alternative impl that uses the CoroutineContext.