I working on a medium-sized Kotlin project where I need to thread configuration information read from file through many nested calls of pure functions. This seems to be an obvious case for the Reader monad. However, I have not figured out how to effectively implement Reader in Kotlin.
I am using the Arrow library (v1.1.3), but - to my surprise - it does not come with an implementation of Reader. What is the preferred way to thread configuration data through function calls with Arrow? As Arrow has shifted to using Kotlin's native suspend system for monad comprehension, I take this to mean that there is no need to have a dedicated Reader implementation. How to do it instead?
Arrow used to have the reader monad in the past, but we've since then stopped supporting such wrappers in favour of Kotlin idiomatic patterns.
There are serveral ways you can solve this in Kotlin, but the most promising is
context receivers.A concrete example can be found here, and a small video tutorial here.
This however is not yet stable in Kotlin, and only available for the JVM for now. There is a way to solve the same issue using extension functions but it currently requires a bit more boilerplate. Where you extend a generic type of
R(Reader), and you constraintRto the instances you require.To then finally call this function you need to make
Rconcrete, you do this by makingRepoandPersistenceand interface and then you can use delegation.It's possible to however still implement
Reader, but it should probably be aReaderTvariant which implements asuspendversion of it.EDIT:
An implementation of
suspendsupportedReaderwith DSL similar to Arrow can be implemented like this: