1

我有一些专门的类,我想使用 Kotlin 和 Arrow 创建它们,它们将环绕 Arrow Either monad。我创建了以下代码来使用 Kotlin 的委托,但我想知道它是否可以简化或变得更惯用。任何建议,将不胜感激。

感谢您的时间与兴趣。

internal data class EitherWrapper<L,R>(private var delegate: Either<L,R>) {
     internal operator fun getValue(thisRef: Any?, property: KProperty<*>): Either<L,R> {
        return delegate
    }

    internal operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Either<L,R>) {
        delegate = value
    }
}

fun main(args: Array<String>) {
    val delegate: Either<Exception, String> = Right("howdy")
    val myeither: Either<Exception, String> by EitherWrapper(delegate)
    println("IsLeft(): ${myeither.isLeft()}")
    println("IsRight(): ${myeither.isRight()}")
}
4

2 回答 2

1

所以,我认为我对我的查询有一个解决方案。以下代码将 Either 包装在一个新类型中:Exceptional。这段代码是我想要构建的起点。最终,我将有如下内容:

在此处输入图像描述

我可以在整个后端服务中传递这种类型的实例,并返回更精确的异常、错误或值。

interface EitherMonad<L, R> {
    val either: Either<L, R>
}

class BaseEitherMonad<L, R>(
    override val either: Either<L, R>
) : EitherMonad<L, R>

class Exceptional<R>(
    private val delegate: EitherMonad<Exception, R>
) : EitherMonad<Exception, R> by delegate {}

fun main() {

    val delegateRight = BaseEitherMonad<Exception, String>(Either.Right("howdy"))
    val exceptionalRight = Exceptional(delegateRight)
    println("IsLeft(): ${exceptionalRight.either.isLeft()}")
    println("IsRight(): ${exceptionalRight.either.isRight()}")
    exceptionalRight.either.fold({ throw it }, { println("Right: $it") })
    exceptionalRight.either.map { println(it) }

    val delegateLeft = BaseEitherMonad<Exception, String>(Either.Left(IllegalStateException("Boom!")))
    val exceptionalLeft = Exceptional(delegateLeft)
    println("IsLeft(): ${exceptionalLeft.either.isLeft()}")
    println("IsRight(): ${exceptionalLeft.either.isRight()}")
    exceptionalLeft.either.fold({ throw it }, { println("Right: $it") })
    exceptionalLeft.either.map { println(it) }
}

运行: 在此处输入图像描述

于 2020-07-31T01:28:02.390 回答
1

您的代码是正确和正确的,据我所知,您可以做的唯一改进是使其通用,而不是特定于任何一个,如下所示:

internal data class DelegateWrapper<T>(private var delegate: T) {
  internal operator fun getValue(thisRef: Any?, property: KProperty<*>): T = 
    delegate

  internal operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
    delegate = value
  }
}
于 2020-07-30T13:52:55.530 回答