Kotlin箭头IO,IO.fx,IO效果之间的区别

问题描述

我正试图在Kotlin中使用箭头

箭头具有三个功能

IO {}
IO.fx {}
IO.fx { !effect}

我想知道两者之间的区别。我知道IO.fx和IO.fx {!effect}可以帮助我们使用副作用,但是两者之间有什么区别,为什么我要在另一个方面使用

解决方法

在版本0.11.X上这很快就会改变:

  • IO { }是一个接受暂停函数的构造函数,因此您可以在其中调用任何暂停函数。这是IO.effect { }
  • 的快捷方式
suspend fun bla(): Unit = ...

fun myIO(): IO<Unit> = IO { bla() }

fun otherIO(): IO<Unit> = IO.effect { bla() }
  • IO.fx { }IO相同,只是它添加了一些DSL功能,这些功能是IO其他API的快捷方式。最重要的是!bind,它们在内部执行另一个IO。
fun myIO(): IO<Unit> = IO.fx { bla() }

fun nestIO(): IO<IO<Unit>> = IO.fx { myIO() }

fun unpackIO(): IO<Unit> = IO.fx { !myIO() }

它启用的另一个功能是从第一点开始的构造函数effect。因此,您实际上正在做的是添加一层不必要的包装材料。

fun inefficientNestIO(): IO<IO<Unit>> = IO.fx { effect { bla() } }

fun inefficientUnpackedIO(): IO<Unit> = IO.fx { !effect { bla() } }

我们经常看到inefficientUnpackedIO来自支持渠道的人,并且很容易由IO { bla() }取代。

为什么在effectfx中有两种相同的方法?我们希望在下一个发行版中对此进行改进。我们建议尽可能使用最不强大的抽象,因此仅在使用其他基于fx的API(例如调度或并行化)时才保留IO

IO.fx {
  val id = getUserIdSuspend()
  val friends: List<User> = 
    !parMapN(
      userFriends(id),IO { userProfile(id) },::toUsers
    )
  !friends.parTraverse(IO.applicative()) { user ->
   IO { broadcastStatus(user) } 
  }
}