typealias Curr = String typealias CurrT = Tuple2 fun main(parameters: String) { val validated: List> = parameters.split(" ").map { when (val split = it.split(":")) { split.length == 2 && (isCurrency(split[0]) && isCurrency(split[1])) -> Validated.validNel(split[0] toT split[1]) else -> Validated.invalidNel(NotInPairFormat(it)) } } val validatedParameters: ValidatedNel> = validated.sequence(Validated.applicative()).fix() val program: IO = validatedParameters.fold({ err: Nel -> IO.raiseError(err) }, { tuples: List -> // Create call to network val request: IO> = tuples.map { (orig: Curr, dest: Curr) -> IO { requestToFixer(orig, dest) } }.sequence(IO.applicative()).fix() fx { // Call with retry val responses: IO> = !request .handleErrorWith { withRetry(it, request, 3) } continueOn(UI) // Display on screen in the UI thread /* Unit */ !displayList(responses) }/* IO */ }) // Start program.unsafeRunAsync {} } fun withRetry(err: Throwable, request: IO>, retries: Int) = if (retries == 0) IO.raiseError(err) else request.handleErrorWith { withRetry(it, request, retries - 1) }