Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin 使用箭头kt验证对象_Kotlin_Arrow Kt - Fatal编程技术网

Kotlin 使用箭头kt验证对象

Kotlin 使用箭头kt验证对象,kotlin,arrow-kt,Kotlin,Arrow Kt,我有一个对象(书),哪些字段应该通过事件更新(作者已更改)。假设书中的作者字段只有在作者结婚并改名后才会改变,但如果作者刚搬到一个新的城市,书中的作者字段不会改变 在这个简单的例子中,我可以检查book.authorName==event.author.name并返回或。但是我怎么能检查不止一个字段呢?如果我继续执行这两种方法中的任何一种,该过程将在它遇到的第一个NothingChangedFailure时停止,但我希望聚合所有更新,并且仅返回NothingChangedFailure,前提是书

我有一个对象(书),哪些字段应该通过事件更新(作者已更改)。假设书中的作者字段只有在作者结婚并改名后才会改变,但如果作者刚搬到一个新的城市,书中的作者字段不会改变

在这个简单的例子中,我可以检查
book.authorName==event.author.name
并返回
。但是我怎么能检查不止一个字段呢?如果我继续执行这两种方法中的任何一种,该过程将在它遇到的第一个
NothingChangedFailure
时停止,但我希望聚合所有更新,并且仅返回
NothingChangedFailure
,前提是书中的任何字段都没有更改

我尝试了
选项
或者
,然后继续阅读
验证
,但我发现,如果出现一次故障,它们似乎都会导致整个结果失败。那么有没有我看不到的选项呢?

有一个例子显示了我们可以组合验证失败的情况

对于你的情况(我将在这里假设一些事情,比如书中可用的字段),我猜它看起来像:

data class Book(val title: String, val authorName: String, val pageCount: Int)
在这里,我们使用半群的定义创建错误:

sealed class BookValidationError {
  data class PropertyNotChanged(val propertyName: String) : BookValidationError()
  data class Multiple(val errors: Nel<BookValidationError>) : BookValidationError()
}

object BookValidationErrorSemigroup : Semigroup<BookValidationError> {
  override fun BookValidationError.combine(b: BookValidationError): BookValidationError = when {
      this is Multiple && b is Multiple -> Multiple(errors + b.errors)
      this is Multiple && b !is Multiple -> Multiple(errors + b)
      this !is Multiple && b is Multiple -> Multiple(this.nel() + b.errors)
      else -> BookValidationError.Multiple(NonEmptyList(this, b))
  } 
}
我们将其与助手类结合在一起:

class BookValidation(
  private val book: Book
) : ApplicativeError<ValidatedPartialOf<BookValidationError>, BookValidationError> by bookApplicativeError {

    fun <T> fieldIsNot(name: String, actualValue: T, incorrectValue: T): Kind<ValidatedPartialOf<BookValidationError>, Book> =
        if(actualValue == incorrectValue) raiseError(BookValidationError.PropertyNotChanged(name))
        else just(book)

}
然后,如果您像这样执行它:

fun main() {
    Book("a", "b", 123).validateThat(
        titleIsNot = "c",
        authorNameIsNot = "d",
        pageCountIsNot = 124
    ).let(::println)
    Book("a", "b", 123).validateThat(
        titleIsNot = "a",
        authorNameIsNot = "b",
        pageCountIsNot = 123
    ).let(::println)
    Book("a", "b", 123).validateThat(
        titleIsNot = "c",
        authorNameIsNot = "b",
        pageCountIsNot = 124
    ).let(::println)
}
第一个将对以下输出有效:

Valid(a=Book(title=a, authorName=b, pageCount=123))
Invalid(e=PropertyNotChanged(propertyName=authorName))
但第二个将输出:

Invalid(e=Multiple(errors=NonEmptyList(all=[PropertyNotChanged(propertyName=pageCount), PropertyNotChanged(propertyName=title), PropertyNotChanged(propertyName=authorName)])))
在这个
Invalid
实例中,我们有一个非空列表,其中包含验证失败的所有字段。如果我们重新格式化一点输出,我们可以看到它们:

Invalid(e=Multiple(
  errors=NonEmptyList(all=[
    PropertyNotChanged(propertyName=pageCount), 
    PropertyNotChanged(propertyName=title), 
    PropertyNotChanged(propertyName=authorName)
  ])
))
现在,对于第三种情况,由于其中只有一种保持不变,我们得到以下输出:

Valid(a=Book(title=a, authorName=b, pageCount=123))
Invalid(e=PropertyNotChanged(propertyName=authorName))

啊,我明白了!我会尽快试一试+谢谢你!这对于验证整本书非常有用,但我仍然无法确定某个属性是否已更改?我需要比较潜在变化的总和和错误的总和?如果错误少于潜在的更改,则说明该书已更改?正如本文所述,只有在所有值均未更改的情况下,此解决方案才会通过。也可以通过一些修改为每个字段创建多个错误,这样您就可以搜索特定故障的结果。它有可能通过反射来推广。我将对其进行更新以简化结果。用更多细节更新了示例。