Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/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 Arrow FX中使用其他效果组合IO函数_Kotlin_Functional Programming_Arrow Kt - Fatal编程技术网

如何在Kotlin Arrow FX中使用其他效果组合IO函数

如何在Kotlin Arrow FX中使用其他效果组合IO函数,kotlin,functional-programming,arrow-kt,Kotlin,Functional Programming,Arrow Kt,在处理请求之前,我们通常需要一些请求验证。使用arrow v 0.8,典型的消息处理程序如下所示: fun addToShoppingCart(request: AddToShoppingCartRequest): IO<Either<ShoppingCardError, ItemAddedEvent>> = fx { request .pipe (::validateShoppingCard) .flatMap { validatedReques

在处理请求之前,我们通常需要一些请求验证。使用arrow v 0.8,典型的消息处理程序如下所示:

fun addToShoppingCart(request: AddToShoppingCartRequest): IO<Either<ShoppingCardError, ItemAddedEvent>> = fx {
    request
    .pipe (::validateShoppingCard)
    .flatMap { validatedRequest ->
        queryShoppingCart().bind().map { validatedRequest to it }         // fun queryShoppingCart(): IO<Either<DatabaseError, ShoppingCart>>
    }
    .flatMap { (validatedRequest, shoppingCart) ->
        maybeAddToShoppingCart(shoppingCart, validatedRequest)            // fun maybeAddToShoppingCart(...): Either<DomainError, ShoppingCart>
    }
    .flatMap { updatedShoppingCart ->
        storeShoppingCart(updatedShoppingCart).bind()                     // fun storeShoppingCart(ShoppingCart): IO<Either<DatabaseError, Unit>>
        .map {
            computeItemAddedEvent(updatedShoppingCart)
        }
    }
    .mapLeft(::computeShoppingCartError)
}
fun addToShoppingCart(请求:addToShoppingCart请求):IO=fx{
要求
.pipe(::validateShoppingCard)
.flatMap{validatedRequest->
queryShoppingCart().bind().map{validatedRequest to it}//fun queryShoppingCart():IO
}
.flatMap{(validatedRequest,shoppingCart)->
maybeAddToShoppingCart(shoppingCart,validatedRequest)//fun maybeAddToShoppingCart(…):或者
}
.flatMap{updatedShoppingCart->
storeShoppingCart(updatedShoppingCart).bind()//有趣的storeShoppingCart(ShoppingCart):IO
.地图{
computeItemAddedEvent(更新的购物车)
}
}
.mapLeft(::computeShoppingCartError)
}
这似乎是对工作流的一个方便而富有表现力的定义。我试图在arrow v 0.10.5中定义类似的函数:

fun handleDownloadRequest(strUrl: String): IO<Either<BadUrl, MyObject>> = IO.fx {
    parseUrl(strUrl)                                                      // fun(String): Either<BadUrl,Url>
    .map {
        !effect{ downloadObject(it) }                                     // suspended fun downloadObject(Url): MyObject
    }
}
乐趣处理下载请求(strUrl:String):IO=IO.fx{ parseUrl(strUrl)//fun(String):或者 .地图{ !effect{downloadObject(it)}//挂起的乐趣下载对象(Url):MyObject } } 这会导致编译器错误“只能在协同程序体中调用挂起函数”。原因是
map
flatMap
功能
选项
都不是
内联的

事实上,关于外汇的报道说

“很快,您就会发现无法在 为上述任一函数声明的函数,以及 其他粉丝的最爱,如map()和handleErrorWith()。为此 需要一个并发库!”

所以问题是为什么会这样?这种作文的惯用方式是什么?

惯用方式是什么

fun handleDownloadRequest(strUrl: String): IO<Either<BadUrl, MyObject>> =
    parseUrl(strUrl)
      .fold({
        IO.just(it.left())  // forward the error
      }, {
        IO { downloadObject(it) }
          .attempt() // get an Either<Throwable, MyObject>
          .map { it.mapLeft { /* Throwable to BadURL */ } } // fix the left side
      })
乐趣处理下载请求(strUrl:String):IO= 解析URL(strUrl) .折叠({ IO.just(it.left())//转发错误 }, { IO{下载对象(it)} .trument()//获取一个 .map{it.mapLeft{/*Throwable to BadURL*/}//修复左侧 }) 就我个人而言,我不会使用这个函数深入IO的最深处,而是将其重写为一个挂起函数

suspend fun handleDownloadRequest(strUrl: String): Either<BadUrl, MyObject> =
    parseUrl(strUrl)
      .fold(::Left) { // forward the error
        Either.catch({ /* Throwable to BadURL */ }) { downloadObject(it) }
      }
suspend-fun-handleDownloadRequest(strUrl:String):或者=
解析URL(strUrl)
.fold(::Left){//转发错误
catch({/*Throwable to BadURL*/}){downloadObject(it)}
}
在0.8.X中,
的函数过去是内联的。这样做的一个意外副作用是,您可以在任何地方调用挂起函数。虽然这很好,但它可能导致抛出异常(或跳转线程或死锁)