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