Search code examples
kotlinfunctional-programmingarrow-kt

Idiomatic Arrow


I have the following method:

internal typealias MaybeError<T> = Either<GenericError, T>

override fun createCompany(companyDomain: CompanyDomain): MaybeError<CompanyDomain> =
    checkCompany(companyDomain).map { it.toEntity() }.fold({ Either.left(it) }) { company ->
        with (companyRepository) {
            isCompanyExists(company).fold({ Either.left(it) }) { isExists ->
                if (isExists) return@with Either.left(CompanyNameExists(companyDomain))
                createCompany(company).fold({ Either.right(companyDomain) }) { Either.left(it) }
            }
        }
    }

Is there a better/more idiomatic way to write this using Arrow?


Solution

  • It is hard to refactor because I can only assume what used methods should return. But I guess the methods returns MaybeError. In this case we can omit fold({ Either.left(it) }) and we can use map or flatMap.

    internal typealias MaybeError<T> = Either<GenericError, T>
    
    override fun createCompany(companyDomain: CompanyDomain): MaybeError<CompanyDomain> =
        checkCompany(companyDomain)
            .map { it.toEntity() }
            .flatMap { company ->
                companyRepository.isCompanyExists(company)
                    .flatMap { isExists ->
                        if (isExists) {
                            MaybeError.left(CompanyNameExists(companyDomain))
                        } else {
                            companyRepository.createCompany(company)
                        }
                    }
            }