Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Kotlin – how to use closure and currying in kotlin to pass a paramater to returned function with multiple arguments?

I have an enum class that looks like this:

enum class CommandTypes(val access: (Ctx) -> Unit, val command: (Ctx, JsonObject) -> Either<Failure, FlatResp>) {
    CREATE_DELIVERED_EVENT(adminOnly, ::createDeliveredEvent),
    CREATE_SWITCHED_EVENT(adminOnly, ::createSwitchedEvent),
    CREATE_STAMPED_EVENT(adminOnly, ::createStampedEvent),

All of this commands/events have the same logic apart from the type of command/event.
They all look like this:

fun createDeliveredEvent(ctx: Ctx, json: JsonObject): Either<Failure, FlatResp> =
    validateAndCreateEvent(ctx, json, EventType.DELIVERED_EVENT)

fun createDeliveredEvent(ctx: Ctx, json: JsonObject): Either<Failure, FlatResp> =
    validateAndCreateEvent(ctx, json, EventType.SWITCHED_EVENT)

fun createDeliveredEvent(ctx: Ctx, json: JsonObject): Either<Failure, FlatResp> =
    validateAndCreateEvent(ctx, json, EventType.STAMPED_EVENT)

Is it possible to pass with currying a type of event to command function, so that I can have a general function that would accept a type and return a function that would have type as an argument. I have tried with something like this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

fun createEvent(type:AirExpressConsignmentEventType): (ctx: Ctx, json: JsonObject) -> Either<Failure, FlatResp> =
{ ctx, json ->  validateAndCreateEvent(ctx, json, type)}

And I am using it like this in the CommandTypes enum class:

CREATE_DELIVERED_EVENT(adminOnly, (::createEvent(EventType.DELIVERED_EVENT)))

But, I get an error:

This syntax is reserved for future use; to call a reference, enclose
it in parentheses: (foo::bar)(args)

I am not sure why do I get that, when I already have another piece of code that works with same syntax?

groups = (::infoGroupingWithContext)(ctx)

fun infoGroupingWithContext(ctx: Ctx): (List<Map<String, Any?>>) -> List<Map<String, Any?>> = { rows -> infoGrouping(ctx, rows) }

>Solution :

The syntax for that would be

fun createEvent(type: EventType): (ctx: Ctx, JsonObject) -> Either<Failure, FlatResp> =
    { ctx, json -> validateAndCreateEvent(ctx, json, type) }

// or perhaps less confusing:

fun createEvent(type: EventType): (ctx: Ctx, JsonObject) -> Either<Failure, FlatResp> {
    return { ctx, json -> validateAndCreateEvent(ctx, json, type) }
}

// or

fun createEvent(type: EventType) = fun (ctx: Ctx, json: JsonObject): Either<Failure, FlatResp> {
    return validateAndCreateEvent(ctx, json, type)
}

But perhaps it would be cleaner to do this instead of having to indirectly call that function:

enum class CommandTypes(
    val access: (Ctx) -> Unit, 
    private val type: EventType
) {
    CREATE_DELIVERED_EVENT(adminOnly, EventType.DELIVERED_EVENT),
    CREATE_SWITCHED_EVENT(adminOnly, EventType.SWITCHED_EVENT),
    CREATE_STAMPED_EVENT(adminOnly, EventType.STAMPED_EVENT);

    val command: (Ctx, JsonObject) -> Either<Failure, FlatResp>) = {
        validateAndCreateEvent(ctx, json, type)
    }
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading