Home > Enterprise >  Kotlin - how to use closure and currying in kotlin to pass a paramater to returned function with mul
Kotlin - how to use closure and currying in kotlin to pass a paramater to returned function with mul

Time:01-25

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:

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) }

CodePudding user response:

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)
    }
}
  •  Tags:  
  • Related