├── api └── arrow-fx-lib.api ├── arrow-benchmarks-fx ├── api │ └── arrow-benchmarks-fx.api ├── gradle.properties ├── arrow-scala-benchmarks │ ├── src │ │ └── main │ │ │ └── scala │ │ │ ├── zio │ │ │ ├── ZIORTS.scala │ │ │ ├── DeepBind.scala │ │ │ ├── Pure.scala │ │ │ ├── Delay.scala │ │ │ ├── AttemptNonRaised.scala │ │ │ ├── LeftBind.scala │ │ │ ├── Map.scala │ │ │ ├── Async.scala │ │ │ ├── AttemptRaisedError.scala │ │ │ └── MapStream.scala │ │ │ └── cats │ │ │ ├── DeepBind.scala │ │ │ ├── Delay.scala │ │ │ ├── Pure.scala │ │ │ ├── AttemptNonRaised.scala │ │ │ ├── LeftBind.scala │ │ │ ├── AttemptRaisedError.scala │ │ │ ├── Map.scala │ │ │ ├── Async.scala │ │ │ └── MapStream.scala │ └── build.gradle ├── arrow-kio-benchmarks │ ├── src │ │ └── main │ │ │ └── kotlin │ │ │ └── kio │ │ │ ├── DeepBind.kt │ │ │ ├── Pure.kt │ │ │ ├── Delay.kt │ │ │ ├── Map.kt │ │ │ ├── LeftBind.kt │ │ │ ├── AttemptNonRaised.kt │ │ │ ├── AttemptRaisedError.kt │ │ │ └── MapStream.kt │ └── build.gradle └── src │ └── jmh │ └── kotlin │ └── arrow │ └── benchmarks │ ├── Uncancellable.kt │ ├── Defer.kt │ ├── ParMap.kt │ ├── ForkFiber.kt │ ├── HandleNonRaised.kt │ ├── Bracket.kt │ ├── Cancellable.kt │ ├── HandleRaisedError.kt │ ├── Async.kt │ ├── RacePair.kt │ ├── Pure.kt │ ├── Delay.kt │ ├── DeepBind.kt │ ├── AttemptNonRaised.kt │ ├── AttemptRaisedError.kt │ └── Queue.kt ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── LICENSE.md ├── arrow-docs ├── docs │ ├── img │ │ └── kotlin-stdlib.png │ └── landscape │ │ └── fx-home-code.md ├── gradle.properties ├── src │ └── main │ │ └── kotlin │ │ ├── GenericHelper.kt │ │ ├── SyntaxHelper.kt │ │ ├── OpticsHelper.kt │ │ ├── DivideHelper.kt │ │ └── AQLHelper.kt └── build.gradle ├── CONTRIBUTING.md ├── arrow-fx-stm ├── gradle.properties ├── README.md ├── build.gradle └── src │ └── test │ └── kotlin │ └── arrow │ └── fx │ └── stm │ ├── TArrayTest.kt │ └── TMapTest.kt ├── arrow-fx-coroutines ├── gradle.properties ├── src │ ├── test │ │ └── kotlin │ │ │ └── arrow │ │ │ └── fx │ │ │ └── coroutines │ │ │ ├── stream │ │ │ ├── PullTest.kt │ │ │ └── Counter.kt │ │ │ ├── CancelBoundary.kt │ │ │ ├── PromiseTest.kt │ │ │ ├── GuaranteeCaseTest.kt │ │ │ └── ForwardCancelableTests.kt │ └── main │ │ └── kotlin │ │ └── arrow │ │ └── fx │ │ └── coroutines │ │ ├── SuspendConnection.kt │ │ ├── predef.kt │ │ ├── evalOn.kt │ │ ├── timer.kt │ │ ├── cancelBoundary.kt │ │ ├── flow.kt │ │ └── stream │ │ └── Pipe.kt └── build.gradle ├── arrow-fx-test ├── gradle.properties ├── build.gradle └── src │ └── main │ └── kotlin │ └── arrow │ └── fx │ └── test │ └── generators │ └── Generators.kt ├── arrow-fx-coroutines-test ├── gradle.properties ├── build.gradle └── src │ └── test │ └── kotlin │ └── arrow │ └── fx │ └── coroutines │ └── PredefTest.kt ├── .editorconfig ├── arrow-fx-coroutines-stream ├── gradle.properties ├── README.MD └── build.gradle ├── arrow-fx-kotlinx-coroutines ├── gradle.properties ├── api │ └── arrow-fx-kotlinx-coroutines.api └── build.gradle ├── arrow-fx-suspend-connection ├── gradle.properties └── build.gradle ├── arrow-fx ├── gradle.properties ├── src │ ├── main │ │ └── kotlin │ │ │ └── arrow │ │ │ └── fx │ │ │ ├── internal │ │ │ ├── Token.kt │ │ │ ├── IOFiber.kt │ │ │ ├── ConcurrentParMap2.kt │ │ │ ├── UnsafePromise.kt │ │ │ └── ConcurrentSleep.kt │ │ │ ├── typeclasses │ │ │ ├── Dispatchers.kt │ │ │ ├── Environment.kt │ │ │ ├── Effect.kt │ │ │ ├── ConcurrentEffect.kt │ │ │ ├── UnsafeRun.kt │ │ │ ├── MonadIO.kt │ │ │ ├── AsyncContinuation.kt │ │ │ ├── ConcurrentContinuation.kt │ │ │ └── MonadDefer.kt │ │ │ ├── SuspendConnection.kt │ │ │ ├── extensions │ │ │ ├── ExitCaseEq.kt │ │ │ ├── io │ │ │ │ ├── monadIO │ │ │ │ │ └── IOMonadIO.kt │ │ │ │ ├── dispatchers │ │ │ │ │ └── IODispatchers.kt │ │ │ │ ├── monadThrow │ │ │ │ │ └── IOMonadThrow.kt │ │ │ │ ├── environment │ │ │ │ │ └── IOEnvironment.kt │ │ │ │ ├── effect │ │ │ │ │ └── IOEffect.kt │ │ │ │ ├── semigroup │ │ │ │ │ └── IOSemigroup.kt │ │ │ │ ├── monoid │ │ │ │ │ └── IOMonoid.kt │ │ │ │ ├── concurrentEffect │ │ │ │ │ └── IODefaultConcurrentEffect.kt │ │ │ │ ├── semigroupK │ │ │ │ │ └── IOSemigroupK.kt │ │ │ │ ├── unsafeCancellableRun │ │ │ │ │ └── IOUnsafeCancellableRun.kt │ │ │ │ ├── unsafeRun │ │ │ │ │ └── IOUnsafeRun.kt │ │ │ │ └── monadError │ │ │ │ │ └── IOMonadError.kt │ │ │ ├── eq │ │ │ │ └── ExitCaseEq.kt │ │ │ ├── duration │ │ │ │ ├── eq │ │ │ │ │ └── DurationEq.kt │ │ │ │ ├── hash │ │ │ │ │ └── DurationHash.kt │ │ │ │ ├── monoid │ │ │ │ │ └── DurationMonoid.kt │ │ │ │ └── semigroup │ │ │ │ │ └── DurationSemigroup.kt │ │ │ ├── invariant │ │ │ │ └── QueueInvariant.kt │ │ │ ├── duration.kt │ │ │ ├── resource │ │ │ │ ├── monadIO │ │ │ │ │ └── ResourceMonadIO.kt │ │ │ │ ├── monoid │ │ │ │ │ └── ResourceMonoid.kt │ │ │ │ └── semigroup │ │ │ │ │ └── ResourceSemigroup.kt │ │ │ ├── QueueInvariant.kt │ │ │ └── schedule │ │ │ │ ├── semigroup │ │ │ │ └── ScheduleSemigroup.kt │ │ │ │ ├── monoid │ │ │ │ └── ScheduleMonoid.kt │ │ │ │ ├── semigroupK │ │ │ │ └── ScheduleSemigroupK.kt │ │ │ │ └── category │ │ │ │ └── ScheduleCategory.kt │ │ │ ├── Timer.kt │ │ │ ├── IOFrame.kt │ │ │ └── IODispatchers.kt │ └── test │ │ └── kotlin │ │ └── arrow │ │ └── fx │ │ ├── EqTest.kt │ │ ├── data │ │ └── DurationTest.kt │ │ ├── FiberTest.kt │ │ └── predef.kt └── build.gradle ├── arrow-fx-rx2 ├── gradle.properties ├── src │ ├── main │ │ └── kotlin │ │ │ └── arrow │ │ │ └── fx │ │ │ └── rx2 │ │ │ ├── predef.kt │ │ │ ├── extensions │ │ │ ├── common.kt │ │ │ ├── maybek │ │ │ │ ├── timer │ │ │ │ │ └── MaybeKTimer.kt │ │ │ │ ├── monadThrow │ │ │ │ │ └── MaybeKMonadThrow.kt │ │ │ │ ├── effect │ │ │ │ │ └── MaybeKEffect.kt │ │ │ │ ├── dispatchers │ │ │ │ │ └── MaybeKDispatchers.kt │ │ │ │ ├── monadFilter │ │ │ │ │ └── MaybeKMonadFilter.kt │ │ │ │ └── unsafeRun │ │ │ │ │ └── MaybeKUnsafeRun.kt │ │ │ ├── singlek │ │ │ │ ├── timer │ │ │ │ │ └── SingleKTimer.kt │ │ │ │ ├── monadThrow │ │ │ │ │ └── SingleKMonadThrow.kt │ │ │ │ ├── effect │ │ │ │ │ └── SingleKEffect.kt │ │ │ │ ├── dispatchers │ │ │ │ │ └── SingleKDispatchers.kt │ │ │ │ ├── concurrentEffect │ │ │ │ │ └── SingleKConcurrentEffect.kt │ │ │ │ └── unsafeRun │ │ │ │ │ └── SingleKUnsafeRun.kt │ │ │ ├── flowablek │ │ │ │ ├── timer │ │ │ │ │ └── FlowableKTimer.kt │ │ │ │ ├── monadThrow │ │ │ │ │ └── FlowableKMonadThrow.kt │ │ │ │ ├── effect │ │ │ │ │ └── FlowableKEffect.kt │ │ │ │ ├── dispatchers │ │ │ │ │ └── FlowableKDispatchers.kt │ │ │ │ ├── concurrentEffect │ │ │ │ │ └── FlowableKConcurrentEffect.kt │ │ │ │ └── monadFilter │ │ │ │ │ └── FlowableKMonadFilter.kt │ │ │ ├── observablek │ │ │ │ ├── timer │ │ │ │ │ └── ObservableKTimer.kt │ │ │ │ ├── monadThrow │ │ │ │ │ └── ObservableKMonadThrow.kt │ │ │ │ ├── effect │ │ │ │ │ └── ObservableKEffect.kt │ │ │ │ ├── dispatchers │ │ │ │ │ └── ObservableKDispatchers.kt │ │ │ │ └── concurrentEffect │ │ │ │ │ └── ObservableKConcurrentEffect.kt │ │ │ └── dispatchers.kt │ │ │ └── CoroutineContextRx2Scheduler.kt │ └── test │ │ └── kotlin │ │ └── arrow │ │ └── fx │ │ └── RxJavaSpec.kt └── build.gradle ├── arrow-fx-reactor ├── gradle.properties ├── src │ └── main │ │ └── kotlin │ │ └── arrow │ │ └── fx │ │ └── reactor │ │ ├── predef.kt │ │ └── extensions │ │ ├── fluxk │ │ ├── timer │ │ │ └── FluxKTimer.kt │ │ ├── monadThrow │ │ │ └── FluxKMonadThrow.kt │ │ ├── effect │ │ │ └── FluxKEffect.kt │ │ ├── concurrentEffect │ │ │ └── FluxKConcurrentEffect.kt │ │ └── monadFilter │ │ │ └── FluxKMonadFilter.kt │ │ └── monok │ │ ├── timer │ │ └── MonoKTimer.kt │ │ ├── monadThrow │ │ └── MonoKMonadThrow.kt │ │ ├── effect │ │ └── MonoKEffect.kt │ │ └── concurrentEffect │ │ └── MonoKConcurrentEffect.kt └── build.gradle ├── arrow-fx-coroutines-kotlinx-coroutines ├── gradle.properties └── build.gradle ├── .github ├── ISSUE_TEMPLATE │ ├── feature_request.md │ └── add-company-logo-to-users.md └── workflows │ ├── check_previous_doc_integration.yml │ ├── check_previous_build_integration.yml │ └── build_doc_arrow-fx.yml ├── scripts └── checkout-orchestrator.sh ├── PULL_REQUEST_TEMPLATE ├── settings.gradle ├── README.md └── gradle.properties /api/arrow-fx-lib.api: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/api/arrow-benchmarks-fx.api: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrow-kt/arrow-fx/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | This is part of [Λrrow](http://arrow-kt.io): [LICENSE](https://github.com/arrow-kt/arrow/blob/master/LICENSE). 2 | -------------------------------------------------------------------------------- /arrow-docs/docs/img/kotlin-stdlib.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrow-kt/arrow-fx/HEAD/arrow-docs/docs/img/kotlin-stdlib.png -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | This is part of [Λrrow](http://arrow-kt.io): [CONTRIBUTING](https://github.com/arrow-kt/arrow/blob/master/CONTRIBUTING.md). 2 | -------------------------------------------------------------------------------- /arrow-fx-stm/gradle.properties: -------------------------------------------------------------------------------- 1 | # Maven publishing configuration 2 | POM_NAME=Arrow-Fx-STM 3 | POM_ARTIFACT_ID=arrow-fx-stm 4 | POM_PACKAGING=jar 5 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/gradle.properties: -------------------------------------------------------------------------------- 1 | # Maven publishing configuration 2 | POM_NAME=Arrow-Benchmarks-Fx 3 | POM_ARTIFACT_ID=arrow-benchmarks-fx 4 | POM_PACKAGING=jar 5 | -------------------------------------------------------------------------------- /arrow-fx-coroutines/gradle.properties: -------------------------------------------------------------------------------- 1 | # Maven publishing configuration 2 | POM_NAME=Arrow-Fx-Coroutines 3 | POM_ARTIFACT_ID=arrow-fx-coroutines 4 | POM_PACKAGING=jar 5 | -------------------------------------------------------------------------------- /arrow-docs/gradle.properties: -------------------------------------------------------------------------------- 1 | # Maven publishing configuration 2 | POM_NAME=Arrow-Fx-Docs 3 | POM_ARTIFACT_ID=arrow-fx-docs 4 | POM_PACKAGING=jar 5 | kapt.incremental.apt=false 6 | -------------------------------------------------------------------------------- /arrow-fx-test/gradle.properties: -------------------------------------------------------------------------------- 1 | # Maven publishing configuration 2 | POM_NAME=Arrow-Fx-Test 3 | POM_ARTIFACT_ID=arrow-fx-test 4 | POM_PACKAGING=jar 5 | kapt.incremental.apt=false 6 | -------------------------------------------------------------------------------- /arrow-fx-coroutines-test/gradle.properties: -------------------------------------------------------------------------------- 1 | # Maven publishing configuration 2 | POM_NAME=Arrow-Fx-Coroutines-Test 3 | POM_ARTIFACT_ID=arrow-fx-coroutines-Test 4 | POM_PACKAGING=jar 5 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Some KtLint rules 2 | [*.{kt,kts}] 3 | indent_size=2 4 | insert_final_newline=true 5 | max_line_length=off 6 | disabled_rules=import-ordering,no-unit-return,curly-spacing 7 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-scala-benchmarks/src/main/scala/zio/ZIORTS.scala: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks.effects.scala.zio 2 | 3 | import zio._ 4 | 5 | object ZIORTS extends DefaultRuntime 6 | -------------------------------------------------------------------------------- /arrow-fx-coroutines-stream/gradle.properties: -------------------------------------------------------------------------------- 1 | # Maven publishing configuration 2 | POM_NAME=Arrow-Fx-Coroutines-Stream 3 | POM_ARTIFACT_ID=arrow-fx-coroutines-stream 4 | POM_PACKAGING=jar 5 | -------------------------------------------------------------------------------- /arrow-fx-kotlinx-coroutines/gradle.properties: -------------------------------------------------------------------------------- 1 | # Maven publishing configuration 2 | POM_NAME=Arrow-Fx-KotlinX-Coroutines 3 | POM_ARTIFACT_ID=arrow-fx-kotlinx-coroutines 4 | POM_PACKAGING=jar 5 | -------------------------------------------------------------------------------- /arrow-fx-suspend-connection/gradle.properties: -------------------------------------------------------------------------------- 1 | # Maven publishing configuration 2 | POM_NAME=Arrow-Fx-Suspend-Connection 3 | POM_ARTIFACT_ID=arrow-fx-suspend-connection 4 | POM_PACKAGING=jar 5 | -------------------------------------------------------------------------------- /arrow-fx/gradle.properties: -------------------------------------------------------------------------------- 1 | # Maven publishing configuration 2 | POM_NAME=Arrow-Fx 3 | POM_ARTIFACT_ID=arrow-fx 4 | POM_PACKAGING=jar 5 | # Build configuration 6 | kapt.incremental.apt=false 7 | -------------------------------------------------------------------------------- /arrow-fx-rx2/gradle.properties: -------------------------------------------------------------------------------- 1 | # Maven publishing configuration 2 | POM_NAME=Arrow-Fx-Rx2 3 | POM_ARTIFACT_ID=arrow-fx-rx2 4 | POM_PACKAGING=jar 5 | # Build configuration 6 | kapt.incremental.apt=false 7 | -------------------------------------------------------------------------------- /arrow-fx-reactor/gradle.properties: -------------------------------------------------------------------------------- 1 | # Maven publishing configuration 2 | POM_NAME=Arrow-Fx-Reactor 3 | POM_ARTIFACT_ID=arrow-fx-reactor 4 | POM_PACKAGING=jar 5 | # Build configuration 6 | kapt.incremental.apt=false 7 | -------------------------------------------------------------------------------- /arrow-fx-coroutines-kotlinx-coroutines/gradle.properties: -------------------------------------------------------------------------------- 1 | # Maven publishing configuration 2 | POM_NAME=Arrow-Fx-Coroutines-KotlinX-Coroutines 3 | POM_ARTIFACT_ID=arrow-fx-coroutines-kotlinx-coroutines 4 | POM_PACKAGING=jar 5 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/internal/Token.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.internal 2 | 3 | /** Represents a unique identifier using object equality. */ 4 | internal class Token { 5 | override fun toString(): String = "Token(${Integer.toHexString(hashCode())})" 6 | } 7 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: What would you like to see in Arrow? 4 | title: [Request] 5 | labels: '' 6 | assignees: Maintainers 7 | 8 | --- 9 | 10 | What version are you currently using? 11 | 12 | What would you like to see? 13 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/typeclasses/Dispatchers.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.typeclasses 2 | 3 | import arrow.fx.IODeprecation 4 | import kotlin.coroutines.CoroutineContext 5 | 6 | @Deprecated(IODeprecation) 7 | interface Dispatchers { 8 | fun default(): CoroutineContext 9 | fun io(): CoroutineContext 10 | } 11 | -------------------------------------------------------------------------------- /scripts/checkout-orchestrator.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ROOTDIR=$1 4 | cd ${ROOTDIR}/.. 5 | BASEDIR=$(pwd) 6 | if [ ! -d arrow ]; then 7 | echo "Clone arrow repository in $BASEDIR/arrow ..." 8 | git clone git@github.com:arrow-kt/arrow.git 2> /dev/null || git clone https://github.com/arrow-kt/arrow.git 9 | fi 10 | -------------------------------------------------------------------------------- /arrow-fx-rx2/src/main/kotlin/arrow/fx/rx2/predef.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.rx2 2 | 3 | internal const val DeprecateRxJava = 4 | "Arrow Fx RxJava is deprecated. Use KotlinX Coroutines RxJava instead to integrate suspend with RxJava." + 5 | "Arrow Fx Coroutines offers all operators that you find in this library in a suspendable way." 6 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/typeclasses/Environment.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.typeclasses 2 | 3 | import arrow.Kind 4 | import arrow.fx.IODeprecation 5 | 6 | @Deprecated(IODeprecation) 7 | interface Environment { 8 | fun dispatchers(): Dispatchers 9 | 10 | fun handleAsyncError(e: Throwable): Kind 11 | } 12 | -------------------------------------------------------------------------------- /arrow-fx-reactor/src/main/kotlin/arrow/fx/reactor/predef.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.reactor 2 | 3 | internal const val DeprecateReactor = 4 | "Arrow Fx Reactor is deprecated. Use KotlinX Coroutines Reactor instead to integrate suspend with Reactor." + 5 | "Arrow Fx Coroutines offers all operators that you find in this library in a suspendable way." 6 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/typeclasses/Effect.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.typeclasses 2 | 3 | import arrow.Kind 4 | import arrow.core.Either 5 | import arrow.fx.IODeprecation 6 | 7 | @Deprecated(IODeprecation) 8 | interface Effect : Async { 9 | fun Kind.runAsync(cb: (Either) -> Kind): Kind 10 | } 11 | -------------------------------------------------------------------------------- /PULL_REQUEST_TEMPLATE: -------------------------------------------------------------------------------- 1 | ## Issue 2 | [n](https://github.com/arrow-kt/arrow-fx/issues/n) 3 | 4 | ## Status 5 | **READY/IN DEVELOPMENT/HOLD** 6 | 7 | ## Description 8 | 9 | 10 | ## Todos 11 | - [ ] Tests 12 | - [ ] Documentation 13 | 14 | ## Related PRs 15 | * None 16 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-scala-benchmarks/src/main/scala/cats/DeepBind.scala: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks.effects.scala.cats 2 | 3 | import cats.effect.IO 4 | 5 | object DeepBind { 6 | 7 | def fib(n: Int): IO[BigInt] = 8 | if (n <= 1) IO(n) 9 | else 10 | fib(n - 1).flatMap { a => 11 | fib(n - 2).flatMap(b => IO(a + b)) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/typeclasses/ConcurrentEffect.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.typeclasses 2 | 3 | import arrow.Kind 4 | import arrow.core.Either 5 | import arrow.fx.IODeprecation 6 | 7 | @Deprecated(IODeprecation) 8 | interface ConcurrentEffect : Effect { 9 | fun Kind.runAsyncCancellable(cb: (Either) -> Kind): Kind 10 | } 11 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-scala-benchmarks/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "org.jetbrains.kotlin.jvm" 3 | id "org.jlleitschuh.gradle.ktlint" 4 | id "scala" 5 | } 6 | 7 | apply from: "$SUB_PROJECT" 8 | 9 | dependencies { 10 | api "org.scala-lang:scala-library:$SCALA_LIBRARY_VERSION" 11 | api "org.typelevel:cats-effect_2.13:$CATS_EFFECT_VERSION" 12 | api "dev.zio:zio_2.13:$DEV_ZIO_VERSION" 13 | } 14 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-scala-benchmarks/src/main/scala/cats/Delay.scala: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks.effects.scala.cats 2 | 3 | import cats.effect.IO 4 | 5 | object Delay { 6 | 7 | def ioDelayLoop(size: Int, i: Int): IO[Int] = 8 | IO(i).flatMap { j => 9 | if (j > size) IO(j) else ioDelayLoop(size, j + 1) 10 | } 11 | 12 | def unsafeIODelayLoop(size: Int, i: Int): Int = 13 | ioDelayLoop(size, i).unsafeRunSync() 14 | 15 | } 16 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-scala-benchmarks/src/main/scala/cats/Pure.scala: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks.effects.scala.cats 2 | 3 | import cats.effect.IO 4 | 5 | object Pure { 6 | 7 | def ioPureLoop(size: Int, i: Int): IO[Int] = 8 | IO.pure(i).flatMap { j => 9 | if (j > size) IO.pure(j) else ioPureLoop(size, j + 1) 10 | } 11 | 12 | def unsafeIOPureLoop(size: Int, i: Int): Int = 13 | ioPureLoop(size, i).unsafeRunSync() 14 | 15 | } 16 | -------------------------------------------------------------------------------- /arrow-fx-stm/README.md: -------------------------------------------------------------------------------- 1 | # Arrow Fx STM 2 | 3 | [![Arrow Fx logo](https://raw.githubusercontent.com/arrow-kt/arrow-site/master/docs/img/fx/arrow-fx-brand-sidebar.svg?sanitize=true)](https://arrow-kt.io) 4 | 5 | Λrrow Fx STM is part of Arrow Fx [**Λrrow**](https://arrow-kt.io/docs/fx/), and the public documentation and information on how to use the library can be found [here](https://arrow-kt.io/docs/next/apidocs/arrow-fx-stm/arrow.fx.stm/-s-t-m/index.html). 6 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-scala-benchmarks/src/main/scala/zio/DeepBind.scala: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks.effects.scala.zio 2 | 3 | import zio._ 4 | 5 | object DeepBind { 6 | 7 | def loop(n: Int): Task[BigInt] = 8 | if (n <= 1) ZIO.effect[BigInt](n) 9 | else 10 | loop(n - 1).flatMap { a => 11 | loop(n - 2).flatMap(b => ZIO.effect(a + b)) 12 | } 13 | 14 | def fib(depth: Int): BigInt = ZIORTS.unsafeRun(loop(depth)) 15 | } 16 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-scala-benchmarks/src/main/scala/zio/Pure.scala: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks.effects.scala.zio 2 | 3 | import zio._ 4 | 5 | object Pure { 6 | 7 | def ioPureLoop(size: Int, i: Int): IO[Nothing, Int] = 8 | IO.succeed(i).flatMap { j => 9 | if (j > size) IO.succeed(j) else ioPureLoop(size, j + 1) 10 | } 11 | 12 | def unsafeIOPureLoop(size: Int, i: Int): Int = 13 | ZIORTS.unsafeRun(ioPureLoop(size, i)) 14 | 15 | } 16 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-scala-benchmarks/src/main/scala/zio/Delay.scala: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks.effects.scala.zio 2 | 3 | import zio._ 4 | 5 | object Delay { 6 | 7 | def ioDelayLoop(size: Int, i: Int): Task[Int] = 8 | ZIO.effect { i } .flatMap { j => 9 | if (j > size) ZIO.effect { j } else ioDelayLoop(size, j + 1) 10 | } 11 | 12 | def unsafeIODelayLoop(size: Int, i: Int): Int = 13 | ZIORTS.unsafeRun(ioDelayLoop(size, i)) 14 | 15 | } 16 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-scala-benchmarks/src/main/scala/cats/AttemptNonRaised.scala: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks.effects.scala.cats 2 | 3 | import cats.effect.IO 4 | 5 | object AttemptNonRaised { 6 | 7 | def ioLoopHappy(size: Int, i: Int): IO[Int] = 8 | if (i < size) { 9 | IO { 10 | i + 1 11 | }.attempt 12 | .flatMap { result => 13 | result.fold[IO[Int]](IO.raiseError[Int], ioLoopHappy(size, _)) 14 | } 15 | } else IO.pure(1) 16 | 17 | } 18 | -------------------------------------------------------------------------------- /arrow-fx-rx2/src/main/kotlin/arrow/fx/rx2/extensions/common.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.rx2.extensions 2 | 3 | import arrow.core.Tuple2 4 | import arrow.core.Tuple3 5 | import io.reactivex.functions.BiFunction 6 | import io.reactivex.functions.Function3 7 | 8 | internal fun tupled2(): BiFunction> = 9 | BiFunction { a: A, b: B -> Tuple2(a, b) } 10 | 11 | internal fun tupled3(): Function3> = 12 | Function3 { a: A, b: B, c: C -> Tuple3(a, b, c) } 13 | -------------------------------------------------------------------------------- /arrow-fx-rx2/src/test/kotlin/arrow/fx/RxJavaSpec.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx 2 | 3 | import arrow.core.test.UnitSpec 4 | import io.kotlintest.Spec 5 | import io.reactivex.plugins.RxJavaPlugins 6 | 7 | abstract class RxJavaSpec : UnitSpec() { 8 | 9 | override fun beforeSpec(spec: Spec) { 10 | super.beforeSpec(spec) 11 | RxJavaPlugins.setErrorHandler { } 12 | } 13 | 14 | override fun afterSpec(spec: Spec) { 15 | super.afterSpec(spec) 16 | RxJavaPlugins.setErrorHandler(null) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/internal/IOFiber.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.internal 2 | 3 | import arrow.fx.ForIO 4 | import arrow.fx.IO 5 | import arrow.fx.coroutines.SuspendConnection 6 | import arrow.fx.typeclasses.Fiber 7 | 8 | internal fun IOFiber(promise: UnsafePromise, conn: SuspendConnection): Fiber { 9 | val join: IO = IO.cancellable { cb -> 10 | promise.get(cb) 11 | 12 | IO { promise.remove(cb) } 13 | } 14 | 15 | return Fiber(join, IO.effect { conn.cancel() }) 16 | } 17 | -------------------------------------------------------------------------------- /arrow-fx-coroutines-stream/README.MD: -------------------------------------------------------------------------------- 1 | # Arrow Fx Coroutines Stream 2 | 3 | [![Arrow Fx logo](https://raw.githubusercontent.com/arrow-kt/arrow-site/master/docs/img/fx/arrow-fx-brand-sidebar.svg?sanitize=true)](https://arrow-kt.io) 4 | 5 | Λrrow Fx Coroutines is part of Arrow Fx [**Λrrow**](https://arrow-kt.io/docs/fx/), and the public documentation and information on how to use the library can be found there. 6 | 7 | Arrow Fx Coroutines Stream is a port of [FS2](https://github.com/typelevel/fs2) on top of Arrow Fx Coroutines. 8 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-kio-benchmarks/src/main/kotlin/kio/DeepBind.kt: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks.effects.kio 2 | 3 | import it.msec.kio.UIO 4 | import it.msec.kio.effect 5 | import it.msec.kio.flatMap 6 | import it.msec.kio.runtime.Runtime 7 | 8 | object DeepBind { 9 | 10 | fun loop(n: Int): UIO = 11 | if (n <= 1) effect { n } 12 | else loop(n - 1).flatMap { a -> 13 | loop(n - 2).flatMap { b -> effect { a + b } } 14 | } 15 | 16 | fun fib(depth: Int) = Runtime.unsafeRunSync(loop(depth)) 17 | } 18 | -------------------------------------------------------------------------------- /arrow-fx-coroutines/src/test/kotlin/arrow/fx/coroutines/stream/PullTest.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.coroutines.stream 2 | 3 | import arrow.fx.coroutines.ArrowFxSpec 4 | import io.kotest.matchers.shouldBe 5 | import io.kotest.property.Arb 6 | import io.kotest.property.arbitrary.int 7 | 8 | class PullTest : ArrowFxSpec( 9 | spec = { 10 | 11 | "pull can output chunks" { 12 | checkAll(Arb.chunk(Arb.int())) { ch -> 13 | Stream(Pull.output(ch)) 14 | .toList() shouldBe ch.toList() 15 | } 16 | } 17 | } 18 | ) 19 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-scala-benchmarks/src/main/scala/cats/LeftBind.scala: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks.effects.scala.cats 2 | 3 | import cats.effect._ 4 | 5 | object LeftBind { 6 | 7 | def loop(depth: Int, size: Int, i: Int): IO[Int] = 8 | if (i % depth == 0) IO(i + 1).flatMap(loop(depth, size, _)) 9 | else if (i < size) loop(depth, size, i + 1).flatMap(i => IO(i)) 10 | else IO(i) 11 | 12 | def unsafeIOLeftBindLoop(depth: Int, size: Int, i: Int): Int = 13 | IO(0).flatMap(loop(depth, size, _)).unsafeRunSync 14 | 15 | } 16 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-scala-benchmarks/src/main/scala/zio/AttemptNonRaised.scala: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks.effects.scala.zio 2 | 3 | import zio._ 4 | 5 | object AttemptNonRaised { 6 | 7 | def ioLoopHappy(size: Int, i: Int): Task[Int] = 8 | if (i < size) { 9 | IO.effect { 10 | i + 1 11 | }.either.flatMap { result => 12 | result.fold[Task[Int]](IO.fail, ioLoopHappy(size, _)) 13 | } 14 | } else IO.succeed(1) 15 | 16 | def run(size: Int) = ZIORTS.unsafeRun(ioLoopHappy(size, 0)) 17 | 18 | } 19 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-kio-benchmarks/src/main/kotlin/kio/Pure.kt: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks.effects.kio 2 | 3 | import it.msec.kio.UIO 4 | import it.msec.kio.flatMap 5 | import it.msec.kio.just 6 | import it.msec.kio.runtime.Runtime 7 | 8 | object Pure { 9 | 10 | fun kioPureLoop(size: Int, i: Int): UIO = 11 | just(i).flatMap { j -> 12 | if (j > size) just(j) else kioPureLoop(size, j + 1) 13 | } 14 | 15 | fun unsafeKIOPureLoop(size: Int, i: Int): Int = 16 | Runtime.unsafeRunSyncAndGet(kioPureLoop(size, i)) 17 | } 18 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'arrow-fx-lib' 2 | 3 | include 'arrow-fx' 4 | include 'arrow-fx-coroutines' 5 | include 'arrow-fx-coroutines-test' 6 | include 'arrow-fx-suspend-connection' 7 | include 'arrow-fx-coroutines-kotlinx-coroutines' 8 | include 'arrow-fx-reactor' 9 | include 'arrow-fx-rx2' 10 | include 'arrow-fx-kotlinx-coroutines' 11 | include 'arrow-benchmarks-fx:arrow-scala-benchmarks' 12 | include 'arrow-benchmarks-fx:arrow-kio-benchmarks' 13 | include 'arrow-benchmarks-fx' 14 | include 'arrow-fx-test' 15 | include 'arrow-fx-stm' 16 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-scala-benchmarks/src/main/scala/zio/LeftBind.scala: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks.effects.scala.zio 2 | 3 | import zio._ 4 | 5 | object LeftBind { 6 | 7 | 8 | def loop(depth: Int, size: Int, i: Int): UIO[Int] = 9 | if (i % depth == 0) IO.effectTotal[Int](i + 1).flatMap { loop(depth, size, _) } 10 | else if (i < size) loop(depth, size, i + 1).flatMap(i => IO.effectTotal(i)) 11 | else IO.effectTotal(i) 12 | 13 | def unsafeIOLeftBindLoop(depth: Int, size: Int, i: Int): Int = 14 | ZIORTS.unsafeRun(loop(depth, size, i)) 15 | 16 | } -------------------------------------------------------------------------------- /arrow-fx-coroutines/src/test/kotlin/arrow/fx/coroutines/stream/Counter.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.coroutines.stream 2 | 3 | import arrow.fx.coroutines.Atomic 4 | 5 | class Counter private constructor(private val atomic: Atomic) { 6 | 7 | suspend fun increment(): Unit = 8 | atomic.update(Int::inc) 9 | 10 | suspend fun decrement(): Unit = 11 | atomic.update(Int::dec) 12 | 13 | suspend fun count(): Int = 14 | atomic.get() 15 | 16 | companion object { 17 | suspend operator fun invoke(): Counter = 18 | Counter(Atomic(0)) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /arrow-fx-test/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "org.jetbrains.kotlin.jvm" 3 | id "org.jlleitschuh.gradle.ktlint" 4 | } 5 | 6 | apply plugin: 'kotlinx-atomicfu' 7 | 8 | apply from: "$SUB_PROJECT" 9 | apply from: "$PUBLICATION" 10 | apply from: "$ANIMALSNIFFER" 11 | 12 | dependencies { 13 | compile project(":arrow-fx") 14 | api "io.arrow-kt:arrow-core-test:$VERSION_NAME" 15 | testRuntime "org.junit.vintage:junit-vintage-engine:$JUNIT_VINTAGE_VERSION" 16 | compile "io.kotlintest:kotlintest-runner-junit5:$KOTLIN_TEST_VERSION", excludeArrow 17 | } 18 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-kio-benchmarks/src/main/kotlin/kio/Delay.kt: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks.effects.kio 2 | 3 | import it.msec.kio.UIO 4 | import it.msec.kio.effect 5 | import it.msec.kio.flatMap 6 | import it.msec.kio.runtime.Runtime 7 | 8 | object Delay { 9 | 10 | private fun kioDelayLoop(size: Int, i: Int): UIO = 11 | effect { i }.flatMap { j -> 12 | if (j > size) effect { j } else kioDelayLoop(size, j + 1) 13 | } 14 | 15 | fun unsafeIODelayLoop(size: Int, i: Int): Int = 16 | Runtime.unsafeRunSyncAndGet(kioDelayLoop(size, i)) 17 | } 18 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-scala-benchmarks/src/main/scala/zio/Map.scala: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks.effects.scala.zio 2 | 3 | import zio._ 4 | 5 | object Map { 6 | 7 | def zioMapTest(iterations: Int, batch: Int): Long = { 8 | val f = { x: Int => x + 1 } 9 | var fx = IO.succeed(0) 10 | 11 | var j = 0 12 | while (j < batch) { 13 | fx = fx.map(f) 14 | j += 1 15 | } 16 | 17 | var sum = 0L 18 | var i = 0 19 | while (i < iterations) { 20 | sum += ZIORTS.unsafeRun(fx) 21 | i += 1 22 | } 23 | sum 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-scala-benchmarks/src/main/scala/cats/AttemptRaisedError.scala: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks.effects.scala.cats 2 | 3 | import cats.effect.IO 4 | 5 | object dummy extends RuntimeException { 6 | override def fillInStackTrace(): Throwable = this 7 | } 8 | 9 | object AttemptRaisedError { 10 | 11 | def ioLoopNotHappy(size: Int, i: Int): IO[Int] = 12 | if (i < size) { 13 | IO { 14 | throw dummy 15 | }.attempt.flatMap { it => 16 | it.fold(_ => ioLoopNotHappy(size, i + 1), IO.pure) 17 | } 18 | } else IO.pure(1) 19 | 20 | } 21 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-scala-benchmarks/src/main/scala/cats/Map.scala: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks.effects.scala.cats 2 | 3 | import cats.effect.IO 4 | 5 | object Map { 6 | 7 | def catsIOMapTest(iterations: Int, batch: Int): Long = { 8 | val f = { x: Int => x + 1 } 9 | var fx = IO.pure(0) 10 | 11 | var j = 0 12 | while (j < batch) { 13 | fx = fx.map(f) 14 | j += 1 15 | } 16 | 17 | var sum = 0L 18 | var i = 0 19 | while (i < iterations) { 20 | sum += fx.unsafeRunSync() 21 | i += 1 22 | } 23 | sum 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /arrow-fx-kotlinx-coroutines/api/arrow-fx-kotlinx-coroutines.api: -------------------------------------------------------------------------------- 1 | public final class arrow/integrations/kotlinx/ExtensionsKt { 2 | public static final fun forkScoped (Larrow/Kind;Lkotlinx/coroutines/CoroutineScope;)Larrow/fx/IO; 3 | public static final fun suspendCancellable (Larrow/Kind;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; 4 | public static final fun unsafeRunIO (Lkotlinx/coroutines/CoroutineScope;Larrow/Kind;Lkotlin/jvm/functions/Function1;)V 5 | public static final fun unsafeRunScoped (Larrow/Kind;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function1;)V 6 | } 7 | 8 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-scala-benchmarks/src/main/scala/cats/Async.scala: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks.effects.scala.cats 2 | 3 | import cats.effect.{ContextShift, IO} 4 | import cats.implicits._ 5 | 6 | import scala.concurrent.ExecutionContext 7 | 8 | object Async { 9 | 10 | implicit val cs: ContextShift[IO] = IO.contextShift(ExecutionContext.global) 11 | 12 | def ioAsyncLoop(size: Int, i: Int): IO[Int] = 13 | IO.shift *> (if (i > size) IO.pure(i) else ioAsyncLoop(size, i + 1)) 14 | 15 | def unsafeIOAsyncLoop(size: Int, i: Int): Int = 16 | ioAsyncLoop(size, i).unsafeRunSync() 17 | 18 | } 19 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-scala-benchmarks/src/main/scala/zio/Async.scala: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks.effects.scala.zio 2 | 3 | import zio._ 4 | import zio.internal.Executor 5 | 6 | import scala.concurrent.ExecutionContext 7 | 8 | object Async { 9 | 10 | val executor: Executor = 11 | Executor.fromExecutionContext(Int.MaxValue)(ExecutionContext.global) 12 | 13 | def ioAsyncLoop(size: Int, i: Int): Task[Int] = 14 | IO.lock(executor)(if (i > size) IO.succeed(i) else ioAsyncLoop(size, i + 1)) 15 | 16 | def unsafeIOAsyncLoop(size: Int, i: Int): Int = 17 | ZIORTS.unsafeRun(ioAsyncLoop(size, i)) 18 | 19 | } 20 | -------------------------------------------------------------------------------- /arrow-fx-coroutines/src/main/kotlin/arrow/fx/coroutines/SuspendConnection.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.coroutines 2 | 3 | /** 4 | * Inline marker to mark a [CancelToken], 5 | * This allows for clearer APIs in functions that expect a [CancelToken] to be returned. 6 | */ 7 | @Suppress("EXPERIMENTAL_FEATURE_WARNING") 8 | inline class CancelToken(val cancel: suspend () -> Unit) { 9 | 10 | suspend fun invoke(): Unit = cancel.invoke() 11 | 12 | override fun toString(): String = "CancelToken(..)" 13 | 14 | companion object { 15 | val unit = CancelToken { Unit } 16 | } 17 | } 18 | 19 | typealias Disposable = () -> Unit 20 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-kio-benchmarks/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "org.jetbrains.kotlin.jvm" 3 | id "org.jlleitschuh.gradle.ktlint" 4 | } 5 | 6 | apply from: "$SUB_PROJECT" 7 | 8 | dependencies { 9 | compile "it.msec:kio:$MSEC_KIO_VERSION" 10 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" 11 | implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$KOTLINX_COROUTINES_VERSION" 12 | } 13 | 14 | compileKotlin { 15 | kotlinOptions.jvmTarget = "1.8" 16 | } 17 | 18 | compileTestKotlin { 19 | kotlinOptions.jvmTarget = "1.8" 20 | } 21 | 22 | repositories { 23 | maven { url "https://jitpack.io" } 24 | } 25 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-kio-benchmarks/src/main/kotlin/kio/Map.kt: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks.effects.kio 2 | 3 | import it.msec.kio.effect 4 | import it.msec.kio.map 5 | import it.msec.kio.runtime.Runtime 6 | 7 | object Map { 8 | 9 | fun kioMapTest(iterations: Int, batch: Int): Long { 10 | val f = { x: Int -> x + 1 } 11 | var fx = effect { 0 } 12 | 13 | var j = 0 14 | while (j < batch) { 15 | fx = fx.map(f) 16 | j += 1 17 | } 18 | 19 | var sum = 0L 20 | var i = 0 21 | while (i < iterations) { 22 | sum += Runtime.unsafeRunSyncAndGet(fx) 23 | i += 1 24 | } 25 | return sum 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /arrow-fx-rx2/src/main/kotlin/arrow/fx/rx2/extensions/maybek/timer/MaybeKTimer.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.rx2.extensions.maybek.timer 2 | 3 | import arrow.fx.rx2.DeprecateRxJava 4 | import arrow.fx.rx2.MaybeK.Companion 5 | import arrow.fx.rx2.extensions.MaybeKTimer 6 | import kotlin.PublishedApi 7 | import kotlin.Suppress 8 | 9 | /** 10 | * cached extension 11 | */ 12 | @PublishedApi() 13 | internal val timer_singleton: MaybeKTimer = object : arrow.fx.rx2.extensions.MaybeKTimer {} 14 | 15 | @Suppress( 16 | "UNCHECKED_CAST", 17 | "NOTHING_TO_INLINE" 18 | ) 19 | @Deprecated(DeprecateRxJava) 20 | inline fun Companion.timer(): MaybeKTimer = timer_singleton 21 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-kio-benchmarks/src/main/kotlin/kio/LeftBind.kt: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks.effects.kio 2 | 3 | import it.msec.kio.UIO 4 | import it.msec.kio.flatMap 5 | import it.msec.kio.just 6 | import it.msec.kio.runtime.Runtime.unsafeRunSyncAndGet 7 | 8 | object LeftBind { 9 | 10 | fun loop(depth: Int, size: Int, i: Int): UIO = 11 | when { 12 | i % depth == 0 -> just(i + 1).flatMap { loop(depth, size, it) } 13 | i < size -> loop(depth, size, i + 1).flatMap { just(it) } 14 | else -> just(i) 15 | } 16 | 17 | fun leftBind(depth: Int, size: Int, i: Int) = 18 | unsafeRunSyncAndGet(loop(depth, size, i)) 19 | } 20 | -------------------------------------------------------------------------------- /arrow-fx-rx2/src/main/kotlin/arrow/fx/rx2/extensions/singlek/timer/SingleKTimer.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.rx2.extensions.singlek.timer 2 | 3 | import arrow.fx.rx2.DeprecateRxJava 4 | import arrow.fx.rx2.SingleK.Companion 5 | import arrow.fx.rx2.extensions.SingleKTimer 6 | import kotlin.PublishedApi 7 | import kotlin.Suppress 8 | 9 | /** 10 | * cached extension 11 | */ 12 | @PublishedApi() 13 | internal val timer_singleton: SingleKTimer = object : arrow.fx.rx2.extensions.SingleKTimer {} 14 | 15 | @Suppress( 16 | "UNCHECKED_CAST", 17 | "NOTHING_TO_INLINE" 18 | ) 19 | @Deprecated(DeprecateRxJava) 20 | inline fun Companion.timer(): SingleKTimer = timer_singleton 21 | -------------------------------------------------------------------------------- /arrow-fx-suspend-connection/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "org.jetbrains.kotlin.jvm" 3 | id "org.jlleitschuh.gradle.ktlint" 4 | } 5 | 6 | apply plugin: 'kotlinx-atomicfu' 7 | 8 | apply from: "$SUB_PROJECT" 9 | apply from: "$DOC_CREATION" 10 | apply from: "$PUBLICATION" 11 | apply from: "$ANIMALSNIFFER" 12 | 13 | dependencies { 14 | testImplementation "io.kotest:kotest-runner-junit5-jvm:$KOTEST_VERSION" // for kotest framework 15 | testImplementation "io.kotest:kotest-assertions-core-jvm:$KOTEST_VERSION" // for kotest core jvm assertions 16 | testImplementation "io.kotest:kotest-property-jvm:$KOTEST_VERSION" // for kotest property test 17 | } 18 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-scala-benchmarks/src/main/scala/zio/AttemptRaisedError.scala: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks.effects.scala.zio 2 | 3 | import zio._ 4 | 5 | object dummy extends RuntimeException { 6 | override def fillInStackTrace(): Throwable = this 7 | } 8 | 9 | object AttemptRaisedError { 10 | 11 | def ioLoopNotHappy(size: Int, i: Int): IO[Nothing, Int] = 12 | if (i < size) { 13 | IO.effect { 14 | throw dummy 15 | }.either.flatMap { it => 16 | it.fold(_ => ioLoopNotHappy(size, i + 1), IO.succeed) 17 | } 18 | } else IO.succeed(1) 19 | 20 | def run(size: Int) = ZIORTS.unsafeRun(ioLoopNotHappy(size, 0)) 21 | 22 | } 23 | -------------------------------------------------------------------------------- /arrow-fx-reactor/src/main/kotlin/arrow/fx/reactor/extensions/fluxk/timer/FluxKTimer.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.reactor.extensions.fluxk.timer 2 | 3 | import arrow.fx.reactor.DeprecateReactor 4 | import arrow.fx.reactor.FluxK.Companion 5 | import arrow.fx.reactor.extensions.FluxKTimer 6 | import kotlin.PublishedApi 7 | import kotlin.Suppress 8 | 9 | /** 10 | * cached extension 11 | */ 12 | @PublishedApi() 13 | internal val timer_singleton: FluxKTimer = object : arrow.fx.reactor.extensions.FluxKTimer {} 14 | 15 | @Suppress( 16 | "UNCHECKED_CAST", 17 | "NOTHING_TO_INLINE" 18 | ) 19 | @Deprecated(DeprecateReactor) 20 | inline fun Companion.timer(): FluxKTimer = timer_singleton 21 | -------------------------------------------------------------------------------- /arrow-fx-reactor/src/main/kotlin/arrow/fx/reactor/extensions/monok/timer/MonoKTimer.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.reactor.extensions.monok.timer 2 | 3 | import arrow.fx.reactor.DeprecateReactor 4 | import arrow.fx.reactor.MonoK.Companion 5 | import arrow.fx.reactor.extensions.MonoKTimer 6 | import kotlin.PublishedApi 7 | import kotlin.Suppress 8 | 9 | /** 10 | * cached extension 11 | */ 12 | @PublishedApi() 13 | internal val timer_singleton: MonoKTimer = object : arrow.fx.reactor.extensions.MonoKTimer {} 14 | 15 | @Suppress( 16 | "UNCHECKED_CAST", 17 | "NOTHING_TO_INLINE" 18 | ) 19 | @Deprecated(DeprecateReactor) 20 | inline fun Companion.timer(): MonoKTimer = timer_singleton 21 | -------------------------------------------------------------------------------- /arrow-fx-kotlinx-coroutines/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "org.jetbrains.kotlin.jvm" 3 | id "org.jlleitschuh.gradle.ktlint" 4 | } 5 | 6 | apply from: "$SUB_PROJECT" 7 | apply from: "$DOC_CREATION" 8 | apply from: "$PUBLICATION" 9 | apply from: "$ANIMALSNIFFER" 10 | 11 | dependencies { 12 | api project(':arrow-fx') 13 | api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$KOTLINX_COROUTINES_VERSION" 14 | 15 | testCompile project(":arrow-fx-test") 16 | testImplementation project(":arrow-fx-test") 17 | testImplementation project(':arrow-fx') 18 | testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$KOTLINX_COROUTINES_VERSION" 19 | } 20 | -------------------------------------------------------------------------------- /arrow-fx-rx2/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "org.jetbrains.kotlin.jvm" 3 | id "org.jlleitschuh.gradle.ktlint" 4 | } 5 | 6 | apply from: "$SUB_PROJECT" 7 | apply from: "$DOC_CREATION" 8 | apply from: "$PUBLICATION" 9 | apply from: "$ANIMALSNIFFER" 10 | 11 | dependencies { 12 | compile project(":arrow-fx") 13 | compile "io.arrow-kt:arrow-annotations:$VERSION_NAME" 14 | testRuntime "org.junit.vintage:junit-vintage-engine:$JUNIT_VINTAGE_VERSION" 15 | testCompile "io.kotlintest:kotlintest-runner-junit5:$KOTLIN_TEST_VERSION", excludeArrow 16 | testCompile project(":arrow-fx-test") 17 | 18 | compile "io.reactivex.rxjava2:rxjava:$RX_JAVA_VERSION" 19 | } 20 | -------------------------------------------------------------------------------- /arrow-fx-rx2/src/main/kotlin/arrow/fx/rx2/extensions/flowablek/timer/FlowableKTimer.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.rx2.extensions.flowablek.timer 2 | 3 | import arrow.fx.rx2.DeprecateRxJava 4 | import arrow.fx.rx2.FlowableK.Companion 5 | import arrow.fx.rx2.extensions.FlowableKTimer 6 | import kotlin.PublishedApi 7 | import kotlin.Suppress 8 | 9 | /** 10 | * cached extension 11 | */ 12 | @PublishedApi() 13 | internal val timer_singleton: FlowableKTimer = object : arrow.fx.rx2.extensions.FlowableKTimer {} 14 | 15 | @Suppress( 16 | "UNCHECKED_CAST", 17 | "NOTHING_TO_INLINE" 18 | ) 19 | @Deprecated(DeprecateRxJava) 20 | inline fun Companion.timer(): FlowableKTimer = timer_singleton 21 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/SuspendConnection.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx 2 | 3 | import arrow.fx.coroutines.SuspendConnection 4 | import arrow.fx.internal.JavaCancellationException 5 | import arrow.fx.typeclasses.Disposable 6 | 7 | @Deprecated(IODeprecation) 8 | enum class OnCancel { 9 | ThrowCancellationException, Silent; 10 | 11 | companion object { 12 | val CancellationException = ConnectionCancellationException 13 | } 14 | } 15 | 16 | @Deprecated(IODeprecation) 17 | object ConnectionCancellationException : JavaCancellationException("User cancellation") 18 | 19 | internal fun SuspendConnection.toDisposable(): Disposable = { 20 | IO.effect { cancel() }.unsafeRunSync() 21 | } 22 | -------------------------------------------------------------------------------- /arrow-fx-rx2/src/main/kotlin/arrow/fx/rx2/extensions/observablek/timer/ObservableKTimer.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.rx2.extensions.observablek.timer 2 | 3 | import arrow.fx.rx2.DeprecateRxJava 4 | import arrow.fx.rx2.ObservableK.Companion 5 | import arrow.fx.rx2.extensions.ObservableKTimer 6 | import kotlin.PublishedApi 7 | import kotlin.Suppress 8 | 9 | /** 10 | * cached extension 11 | */ 12 | @PublishedApi() 13 | internal val timer_singleton: ObservableKTimer = object : arrow.fx.rx2.extensions.ObservableKTimer 14 | {} 15 | 16 | @Suppress( 17 | "UNCHECKED_CAST", 18 | "NOTHING_TO_INLINE" 19 | ) 20 | @Deprecated(DeprecateRxJava) 21 | inline fun Companion.timer(): ObservableKTimer = timer_singleton 22 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/typeclasses/UnsafeRun.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.typeclasses 2 | 3 | import arrow.Kind 4 | import arrow.core.Either 5 | import arrow.fx.IODeprecation 6 | import arrow.fx.OnCancel 7 | import arrow.unsafe 8 | 9 | @Deprecated(IODeprecation) 10 | interface UnsafeRun { 11 | suspend fun unsafe.runBlocking(fa: () -> Kind): A 12 | suspend fun unsafe.runNonBlocking(fa: () -> Kind, cb: (Either) -> Unit): Unit 13 | } 14 | 15 | @Deprecated(IODeprecation) 16 | interface UnsafeCancellableRun : UnsafeRun { 17 | suspend fun unsafe.runNonBlockingCancellable(onCancel: OnCancel, fa: () -> Kind, cb: (Either) -> Unit): Disposable 18 | } 19 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/add-company-logo-to-users.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Add company logo to users 3 | about: 'If you’re using Arrow in Production, submit this issue to get your logo added 4 | to the Arrow_kt.io website under the list of users! ' 5 | title: "[Add company logo]" 6 | labels: Arrow in Production 7 | assignees: MaureenElsberry 8 | 9 | --- 10 | 11 | **Company Name:** 12 | 13 | **Website:** 14 | 15 | **Logo:** 16 | 17 | Please upload a high-res logo of either .svg or .png to this issue. 18 | 19 | - [ ] By checking this box, I’m confirming that I have permission to add this company to the public list of users. 20 | 21 | **Optional Information:** 22 | 23 | Tell us a bit on how you’re using Arrow! We’d love to hear it: 24 | -------------------------------------------------------------------------------- /arrow-fx-reactor/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "org.jetbrains.kotlin.jvm" 3 | id "org.jlleitschuh.gradle.ktlint" 4 | } 5 | 6 | apply from: "$SUB_PROJECT" 7 | apply from: "$DOC_CREATION" 8 | apply from: "$PUBLICATION" 9 | 10 | dependencies { 11 | compile project(":arrow-fx") 12 | compile "io.arrow-kt:arrow-annotations:$VERSION_NAME" 13 | testRuntime "org.junit.vintage:junit-vintage-engine:$JUNIT_VINTAGE_VERSION" 14 | testCompile "io.kotlintest:kotlintest-runner-junit5:$KOTLIN_TEST_VERSION", excludeArrow 15 | testCompile project(":arrow-fx-test") 16 | 17 | compile "io.projectreactor:reactor-core:$PROJECT_REACTOR_VERSION" 18 | testCompile "io.projectreactor:reactor-test:$PROJECT_REACTOR_VERSION" 19 | } 20 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/extensions/ExitCaseEq.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.extensions 2 | 3 | import arrow.fx.IODeprecation 4 | import arrow.fx.typeclasses.ExitCase 5 | import arrow.typeclasses.Eq 6 | 7 | @Deprecated(IODeprecation) 8 | interface ExitCaseEq : Eq> { 9 | fun EQE(): Eq 10 | 11 | override fun ExitCase.eqv(b: ExitCase): Boolean = when (this) { 12 | ExitCase.Completed -> when (b) { 13 | ExitCase.Completed -> true 14 | else -> false 15 | } 16 | ExitCase.Cancelled -> when (b) { 17 | ExitCase.Cancelled -> true 18 | else -> false 19 | } 20 | is ExitCase.Error -> when (b) { 21 | is ExitCase.Error -> EQE().run { e.eqv(b.e) } 22 | else -> false 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /arrow-fx-coroutines-test/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "org.jetbrains.kotlin.jvm" 3 | id "org.jlleitschuh.gradle.ktlint" 4 | } 5 | 6 | apply plugin: 'kotlinx-atomicfu' 7 | 8 | apply from: "$SUB_PROJECT" 9 | apply from: "$DOC_CREATION" 10 | apply from: "$PUBLICATION" 11 | apply from: "$ANIMALSNIFFER" 12 | 13 | dependencies { 14 | api "io.arrow-kt:arrow-core:$VERSION_NAME" 15 | api project(":arrow-fx-coroutines") 16 | api project(":arrow-fx-suspend-connection") 17 | 18 | api "io.kotest:kotest-runner-junit5-jvm:$KOTEST_VERSION" // for kotest framework 19 | api "io.kotest:kotest-assertions-core-jvm:$KOTEST_VERSION" // for kotest core jvm assertions 20 | api "io.kotest:kotest-property-jvm:$KOTEST_VERSION" // for kotest property test 21 | } 22 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-kio-benchmarks/src/main/kotlin/kio/AttemptNonRaised.kt: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks.effects.kio 2 | 3 | import it.msec.kio.Task 4 | import it.msec.kio.attempt 5 | import it.msec.kio.effect 6 | import it.msec.kio.just 7 | import it.msec.kio.recover 8 | import it.msec.kio.flatMap 9 | import it.msec.kio.result.getOrThrow 10 | import it.msec.kio.runtime.Runtime 11 | 12 | object AttemptNonRaised { 13 | 14 | fun attemptNonRaised(size: Int): Int = Runtime.unsafeRunSync(loopHappy(size, 0)).getOrThrow() 15 | 16 | fun loopHappy(size: Int, i: Int): Task = 17 | if (i < size) { 18 | effect { i + 1 } 19 | .attempt() 20 | .recover { throw RuntimeException("not happening") } 21 | .flatMap { loopHappy(size, it) } 22 | } else 23 | just(1) 24 | } 25 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-kio-benchmarks/src/main/kotlin/kio/AttemptRaisedError.kt: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks.effects.kio 2 | 3 | import it.msec.kio.Task 4 | import it.msec.kio.attempt 5 | import it.msec.kio.effect 6 | import it.msec.kio.just 7 | import it.msec.kio.tryRecover 8 | 9 | object AttemptRaisedError { 10 | 11 | private val dummy = object : RuntimeException("dummy") { 12 | override fun fillInStackTrace(): Throwable = 13 | this 14 | } 15 | 16 | private fun loopNotHappy(size: Int, i: Int): Task = 17 | if (i < size) { 18 | effect { throw dummy } 19 | .attempt() 20 | .tryRecover { loopNotHappy(size, i + 1) } 21 | } else 22 | just(1) 23 | 24 | fun attemptRaisedError(size: Int) = 25 | it.msec.kio.runtime.Runtime.unsafeRunSync(loopNotHappy(size, 0)) 26 | } 27 | -------------------------------------------------------------------------------- /arrow-fx/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "org.jetbrains.kotlin.jvm" 3 | id "org.jlleitschuh.gradle.ktlint" 4 | } 5 | 6 | apply plugin: 'kotlinx-atomicfu' 7 | 8 | apply from: "$SUB_PROJECT" 9 | apply from: "$DOC_CREATION" 10 | apply from: "$PUBLICATION" 11 | apply from: "$ANIMALSNIFFER" 12 | 13 | dependencies { 14 | implementation project(":arrow-fx-suspend-connection") 15 | implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$KOTLINX_COROUTINES_VERSION" 16 | 17 | compile "io.arrow-kt:arrow-core:$VERSION_NAME" 18 | 19 | testCompile "io.kotlintest:kotlintest-runner-junit5:$KOTLIN_TEST_VERSION", excludeArrow 20 | testCompile project(":arrow-fx-coroutines") 21 | testCompile project(":arrow-fx-test") 22 | testRuntime "org.junit.vintage:junit-vintage-engine:$JUNIT_VINTAGE_VERSION" 23 | } 24 | -------------------------------------------------------------------------------- /arrow-fx/src/test/kotlin/arrow/fx/EqTest.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx 2 | 3 | import arrow.core.test.laws.equalUnderTheLaw 4 | import arrow.fx.internal.TimeoutException 5 | import arrow.fx.typeclasses.milliseconds 6 | import arrow.fx.test.eq.eq 7 | import arrow.fx.test.laws.shouldBeEq 8 | import arrow.fx.test.laws.shouldNotBeEq 9 | import io.kotlintest.shouldThrow 10 | 11 | class EqTest : ArrowFxSpec() { 12 | 13 | init { 14 | "Should pass pure equal values" { 15 | IO.just(true).shouldBeEq(IO.just(true), IO.eq()) 16 | } 17 | 18 | "Should fail for pure non-equal values" { 19 | IO.just(true).shouldNotBeEq(IO.just(false), IO.eq()) 20 | } 21 | 22 | "Times out" { 23 | shouldThrow { 24 | IO.never.equalUnderTheLaw(IO.just(1), IO.eq(timeout = 10.milliseconds)) 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /arrow-fx-stm/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "org.jetbrains.kotlin.jvm" 3 | id "org.jlleitschuh.gradle.ktlint" 4 | } 5 | 6 | apply plugin: 'kotlinx-atomicfu' 7 | 8 | apply from: "$SUB_PROJECT" 9 | apply from: "$DOC_CREATION" 10 | apply from: "$PUBLICATION" 11 | apply from: "$ANIMALSNIFFER" 12 | 13 | dependencies { 14 | api "io.arrow-kt:arrow-core:$VERSION_NAME" 15 | implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$KOTLINX_COROUTINES_VERSION" 16 | 17 | testImplementation project(":arrow-fx-coroutines-test") 18 | testImplementation "io.kotest:kotest-runner-junit5-jvm:$KOTEST_VERSION" // for kotest framework 19 | testImplementation "io.kotest:kotest-assertions-core-jvm:$KOTEST_VERSION" // for kotest core jvm assertions 20 | testImplementation "io.kotest:kotest-property-jvm:$KOTEST_VERSION" // for kotest property test 21 | } 22 | -------------------------------------------------------------------------------- /arrow-fx-coroutines/src/main/kotlin/arrow/fx/coroutines/predef.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.coroutines 2 | 3 | import kotlin.coroutines.Continuation 4 | import kotlin.coroutines.intrinsics.createCoroutineUnintercepted 5 | import kotlin.coroutines.resume 6 | 7 | internal inline infix fun ((A) -> B).andThen(crossinline f: (B) -> C): (A) -> C = 8 | { a -> f(this(a)) } 9 | 10 | internal fun Iterable<*>.size(): Int = 11 | when (this) { 12 | is Collection -> size 13 | else -> fold(0) { acc, _ -> acc + 1 } 14 | } 15 | 16 | internal fun (suspend () -> A).startCoroutineUnintercepted(completion: Continuation): Unit = 17 | createCoroutineUnintercepted(completion).resume(Unit) 18 | 19 | /** Represents a unique identifier using object equality. */ 20 | internal class Token { 21 | override fun toString(): String = "Token(${Integer.toHexString(hashCode())})" 22 | } 23 | -------------------------------------------------------------------------------- /arrow-fx-coroutines-kotlinx-coroutines/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "org.jetbrains.kotlin.jvm" 3 | id "org.jlleitschuh.gradle.ktlint" 4 | } 5 | 6 | apply from: "$SUB_PROJECT" 7 | apply from: "$DOC_CREATION" 8 | apply from: "$PUBLICATION" 9 | apply from: "$ANIMALSNIFFER" 10 | 11 | dependencies { 12 | implementation project(':arrow-fx-coroutines') 13 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$KOTLIN_VERSION" 14 | implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$KOTLINX_COROUTINES_VERSION" 15 | 16 | testImplementation "io.kotest:kotest-runner-junit5-jvm:$KOTEST_VERSION" 17 | testImplementation "io.kotest:kotest-assertions-core-jvm:$KOTEST_VERSION" 18 | testImplementation "io.kotest:kotest-property-jvm:$KOTEST_VERSION" 19 | testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$KOTLINX_COROUTINES_VERSION" 20 | } 21 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/typeclasses/MonadIO.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.typeclasses 2 | 3 | import arrow.Kind 4 | import arrow.fx.IO 5 | import arrow.fx.IODeprecation 6 | import arrow.typeclasses.Monad 7 | 8 | /** 9 | * Lift concrete [IO] into a polymorphic monad [M]. This is used to call [IO] from mtl style programs which don't have a concrete type. 10 | * This is in theory enough to define the entire effect hierarchy up to [Concurrent] however those instances might have different semantics for different 11 | * types which is why it is not done here. If one wants to use [Concurrent] methods by only delegating to [IO] simply perform the task in [IO] and lift it. 12 | * If that is not enough use the fx-mtl package for better instances of the effect hierarchy. 13 | **/ 14 | @Deprecated(IODeprecation) 15 | interface MonadIO : Monad { 16 | fun IO.liftIO(): Kind 17 | } 18 | -------------------------------------------------------------------------------- /arrow-fx-coroutines/src/main/kotlin/arrow/fx/coroutines/evalOn.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.coroutines 2 | 3 | import kotlinx.coroutines.withContext 4 | import kotlin.coroutines.CoroutineContext 5 | 6 | @Deprecated("Use withContext", replaceWith = ReplaceWith("withContext(ctx, block)", "kotlinx.coroutines.withContext")) 7 | suspend fun (suspend () -> T).evalOn(ctx: CoroutineContext): T = 8 | withContext(ctx) { this@evalOn.invoke() } 9 | 10 | /** 11 | * Executes a task on [context] and comes back to the original [CoroutineContext]. 12 | * 13 | * State of [context] and previous [CoroutineContext] is merged 14 | */ 15 | @Deprecated( 16 | "Use withContext", 17 | replaceWith = ReplaceWith("withContext(context, block)", "kotlinx.coroutines.withContext") 18 | ) 19 | suspend fun evalOn( 20 | context: CoroutineContext, 21 | block: suspend () -> T 22 | ): T = withContext(context) { block.invoke() } 23 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/typeclasses/AsyncContinuation.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.typeclasses 2 | 3 | import arrow.fx.IODeprecation 4 | import arrow.typeclasses.MonadThrowSyntax 5 | import arrow.typeclasses.MonadThrowContinuation 6 | import kotlin.coroutines.CoroutineContext 7 | import kotlin.coroutines.EmptyCoroutineContext 8 | import kotlin.coroutines.RestrictsSuspension 9 | 10 | @Deprecated(IODeprecation) 11 | typealias Disposable = () -> Unit 12 | 13 | @RestrictsSuspension 14 | @Deprecated(IODeprecation) 15 | interface AsyncSyntax : MonadThrowSyntax, Async 16 | 17 | @Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE") 18 | @Deprecated(IODeprecation) 19 | open class AsyncContinuation(val SC: Async, override val context: CoroutineContext = EmptyCoroutineContext) : 20 | MonadThrowContinuation(SC), Async by SC, AsyncSyntax { 21 | override val fx: AsyncFx = SC.fx 22 | } 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Arrow Fx 2 | 3 | [![Arrow Fx logo](https://raw.githubusercontent.com/arrow-kt/arrow-site/master/docs/img/fx/arrow-fx-brand-sidebar.svg?sanitize=true)](https://arrow-kt.io) 4 | 5 | Λrrow Fx is part of [**Λrrow**](https://arrow-kt.io). 6 | 7 | Global properties and checks come from [**arrow**](https://github.com/arrow-kt/arrow) repository. 8 | 9 | ## How-tos 10 | 11 | * [How to build the library](https://github.com/arrow-kt/arrow/blob/master/docs/libraries/how-to-build-a-library.md) 12 | * [How to generate and validate the documentation](https://github.com/arrow-kt/arrow/blob/master/docs/libraries/how-to-generate-and-validate-documentation.md) 13 | * [How to run the website in your local server](https://github.com/arrow-kt/arrow/blob/master/docs/libraries/how-to-run-the-website-in-your-local-server.md) 14 | * [How to propose an improvement](https://github.com/arrow-kt/arrow/blob/master/docs/libraries/how-to-propose-an-improvement.md) 15 | -------------------------------------------------------------------------------- /arrow-docs/src/main/kotlin/GenericHelper.kt: -------------------------------------------------------------------------------- 1 | package arrow.generic 2 | 3 | data class Account(val balance: Int, val available: Int) { 4 | companion object 5 | } 6 | 7 | data class Speed(val kmh: Int) { 8 | companion object 9 | } 10 | 11 | data class Car(val speed: Speed) { 12 | companion object 13 | } 14 | 15 | data class Salesperson(val name: String) 16 | data class Dealership(val location: String) 17 | 18 | sealed class CommonServerError 19 | object ServerError : CommonServerError() 20 | object UserUnauthorized : CommonServerError() 21 | object OverRequestLimit : CommonServerError() 22 | 23 | sealed class RegistrationError 24 | object CarAlreadyRegistered : RegistrationError() 25 | object StolenCar : RegistrationError() 26 | 27 | data class SuccessfullyRegistered(val registration: Registration) 28 | 29 | data class Registration(val car: Car) 30 | 31 | interface Database { 32 | fun insertRegistration(registration: Registration) 33 | } 34 | -------------------------------------------------------------------------------- /arrow-fx-coroutines/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "org.jetbrains.kotlin.jvm" 3 | id "org.jlleitschuh.gradle.ktlint" 4 | } 5 | 6 | apply plugin: 'kotlinx-atomicfu' 7 | 8 | apply from: "$SUB_PROJECT" 9 | apply from: "$DOC_CREATION" 10 | apply from: "$PUBLICATION" 11 | 12 | dependencies { 13 | api "io.arrow-kt:arrow-core:$VERSION_NAME" 14 | implementation project(":arrow-fx-suspend-connection") 15 | implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$KOTLINX_COROUTINES_VERSION" 16 | 17 | testImplementation project(":arrow-fx-coroutines-test") 18 | testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$KOTLINX_COROUTINES_VERSION" 19 | testImplementation "io.kotest:kotest-runner-junit5-jvm:$KOTEST_VERSION" // for kotest framework 20 | testImplementation "io.kotest:kotest-assertions-core-jvm:$KOTEST_VERSION" // for kotest core jvm assertions 21 | testImplementation "io.kotest:kotest-property-jvm:$KOTEST_VERSION" // for kotest property test 22 | } 23 | -------------------------------------------------------------------------------- /arrow-fx-coroutines-stream/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "org.jetbrains.kotlin.jvm" 3 | id "org.jlleitschuh.gradle.ktlint" 4 | } 5 | 6 | apply plugin: 'kotlinx-atomicfu' 7 | 8 | apply from: "$SUB_PROJECT" 9 | apply from: "$DOC_CREATION" 10 | apply from: "$PUBLICATION" 11 | apply from: "$ANIMALSNIFFER" 12 | 13 | dependencies { 14 | api "io.arrow-kt:arrow-core:$VERSION_NAME" 15 | implementation project(":arrow-fx-coroutines") 16 | implementation project(":arrow-fx-suspend-connection") 17 | implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$KOTLINX_COROUTINES_VERSION" 18 | 19 | testImplementation project(":arrow-fx-coroutines-test") 20 | testImplementation "io.kotest:kotest-runner-junit5-jvm:$KOTEST_VERSION" // for kotest framework 21 | testImplementation "io.kotest:kotest-assertions-core-jvm:$KOTEST_VERSION" // for kotest core jvm assertions 22 | testImplementation "io.kotest:kotest-property-jvm:$KOTEST_VERSION" // for kotest property test 23 | } 24 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/extensions/io/monadIO/IOMonadIO.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.extensions.io.monadIO 2 | 3 | import arrow.fx.IO 4 | import arrow.fx.IO.Companion 5 | import arrow.fx.IODeprecation 6 | import arrow.fx.extensions.IOMonadIO 7 | import kotlin.Deprecated 8 | import kotlin.PublishedApi 9 | import kotlin.Suppress 10 | import kotlin.jvm.JvmName 11 | 12 | /** 13 | * cached extension 14 | */ 15 | @PublishedApi() 16 | internal val monadIO_singleton: IOMonadIO = object : arrow.fx.extensions.IOMonadIO {} 17 | 18 | @JvmName("liftIO") 19 | @Suppress( 20 | "UNCHECKED_CAST", 21 | "USELESS_CAST", 22 | "EXTENSION_SHADOWED_BY_MEMBER", 23 | "UNUSED_PARAMETER" 24 | ) 25 | @Deprecated(IODeprecation) 26 | fun IO.liftIO(): IO = arrow.fx.IO.monadIO().run { 27 | this@liftIO.liftIO() as arrow.fx.IO 28 | } 29 | 30 | @Suppress( 31 | "UNCHECKED_CAST", 32 | "NOTHING_TO_INLINE" 33 | ) 34 | @Deprecated(IODeprecation) 35 | inline fun Companion.monadIO(): IOMonadIO = monadIO_singleton 36 | -------------------------------------------------------------------------------- /arrow-fx-coroutines/src/test/kotlin/arrow/fx/coroutines/CancelBoundary.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.coroutines 2 | 3 | import io.kotest.core.spec.style.StringSpec 4 | import io.kotest.matchers.types.shouldBeInstanceOf 5 | import kotlinx.coroutines.delay 6 | import kotlin.time.ExperimentalTime 7 | import kotlin.time.seconds 8 | 9 | @ExperimentalTime 10 | class CancelBoundary : StringSpec({ 11 | 12 | suspend fun forever(): Unit { 13 | while (true) { 14 | cancelBoundary() // cancellable computation loop 15 | } 16 | } 17 | 18 | "endless loop can be cancelled if it includes a boundary" { 19 | val latch = Promise() 20 | val exit = Promise() 21 | val f = ForkConnected { 22 | guaranteeCase( 23 | { 24 | latch.complete(Unit) 25 | forever() 26 | }, 27 | { ec -> exit.complete(ec) } 28 | ) 29 | } 30 | latch.get() 31 | f.cancel() 32 | exit.get().shouldBeInstanceOf() 33 | delay(1.seconds) 34 | } 35 | }) 36 | -------------------------------------------------------------------------------- /.github/workflows/check_previous_doc_integration.yml: -------------------------------------------------------------------------------- 1 | name: "Check Previous Doc Integration" 2 | 3 | on: pull_request 4 | 5 | jobs: 6 | check-previous_doc-integration: 7 | 8 | env: 9 | BASEDIR: ${{github.workspace}}/.. 10 | JAVA_OPTS: -Xms512m -Xmx1024m 11 | 12 | runs-on: macos-latest 13 | timeout-minutes: 90 14 | 15 | steps: 16 | - uses: actions/checkout@v2 17 | - name: Checkout orchestrator 18 | env: 19 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 20 | run: | 21 | BRANCH_NAME=${{ github.event.pull_request.head.ref }} 22 | git clone https://github.com/arrow-kt/arrow.git $BASEDIR/arrow --depth 1 --no-single-branch 23 | . $BASEDIR/arrow/scripts/commons4gradle.sh 24 | updateOrchestrator $BRANCH_NAME 25 | - name: Check Doc Integration 26 | env: 27 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 28 | run: | 29 | BRANCH_NAME=${{ github.event.pull_request.head.ref }} 30 | $BASEDIR/arrow/scripts/check-doc-integration.sh $BRANCH_NAME 31 | -------------------------------------------------------------------------------- /arrow-docs/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | maven { url "https://oss.jfrog.org/artifactory/oss-snapshot-local/" } 4 | } 5 | dependencies { 6 | classpath "io.arrow-kt:arrow-ank-gradle:$VERSION_NAME" 7 | } 8 | } 9 | 10 | plugins { 11 | id "org.jetbrains.kotlin.jvm" 12 | id "org.jetbrains.kotlin.kapt" 13 | id "org.jlleitschuh.gradle.ktlint" 14 | } 15 | 16 | apply from: "$SUB_PROJECT" 17 | apply from: "$DOC_VALIDATION" 18 | 19 | dependencies { 20 | compile "io.arrow-kt:arrow-optics:$VERSION_NAME" 21 | compile "io.arrow-kt:arrow-ui:$VERSION_NAME" 22 | compile "io.arrow-kt:arrow-syntax:$VERSION_NAME" 23 | compile "io.arrow-kt:arrow-meta:$VERSION_NAME" 24 | compile project(":arrow-fx") 25 | compile project(":arrow-fx-coroutines") 26 | compile project(":arrow-fx-stm") 27 | compile project(":arrow-fx-rx2") 28 | compile project(":arrow-fx-reactor") 29 | compile project(":arrow-fx-kotlinx-coroutines") 30 | kapt "io.arrow-kt:arrow-meta:$VERSION_NAME" 31 | } 32 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Build properties 2 | COMMON_SETUP=https://raw.githubusercontent.com/arrow-kt/arrow/master/gradle/setup.gradle 3 | ROOT_PROJECT=https://raw.githubusercontent.com/arrow-kt/arrow/master/gradle/main.gradle 4 | SUB_PROJECT=https://raw.githubusercontent.com/arrow-kt/arrow/master/gradle/subproject.gradle 5 | DOC_CREATION=https://raw.githubusercontent.com/arrow-kt/arrow/master/gradle/apidoc-creation.gradle 6 | DOC_VALIDATION=https://raw.githubusercontent.com/arrow-kt/arrow/master/gradle/doc-validation.gradle 7 | PUBLICATION=https://raw.githubusercontent.com/arrow-kt/arrow/master/gradle/publication.gradle 8 | ANIMALSNIFFER=https://raw.githubusercontent.com/arrow-kt/arrow/master/gradle/animalsniffer.gradle 9 | # Gradle options 10 | org.gradle.jvmargs=-Xmx4g 11 | org.gradle.parallel=true 12 | # Kotlin configuration 13 | kotlin.incremental=true 14 | # Kotlin Test configuration 15 | #Parallelism needs to be set to 1 since the concurrent tests in arrow-effects become flaky otherwise 16 | kotlintest.parallelism=1 17 | kapt.incremental.apt=false 18 | -------------------------------------------------------------------------------- /.github/workflows/check_previous_build_integration.yml: -------------------------------------------------------------------------------- 1 | name: "Check Previous Build Integration" 2 | 3 | on: pull_request 4 | 5 | jobs: 6 | check-previous_build-integration: 7 | 8 | env: 9 | BASEDIR: ${{github.workspace}}/.. 10 | JAVA_OPTS: -Xms512m -Xmx1024m 11 | 12 | runs-on: macos-latest 13 | timeout-minutes: 90 14 | 15 | steps: 16 | - uses: actions/checkout@v2 17 | - name: Checkout orchestrator 18 | env: 19 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 20 | run: | 21 | BRANCH_NAME=${{ github.event.pull_request.head.ref }} 22 | git clone https://github.com/arrow-kt/arrow.git $BASEDIR/arrow --depth 1 --no-single-branch 23 | . $BASEDIR/arrow/scripts/commons4gradle.sh 24 | updateOrchestrator $BRANCH_NAME 25 | - name: Check Build Integration 26 | env: 27 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 28 | run: | 29 | BRANCH_NAME=${{ github.event.pull_request.head.ref }} 30 | $BASEDIR/arrow/scripts/check-build-integration.sh $BRANCH_NAME 31 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/extensions/eq/ExitCaseEq.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.extensions.exitcase.eq 2 | 3 | import arrow.fx.IODeprecation 4 | import arrow.fx.extensions.ExitCaseEq 5 | import arrow.fx.typeclasses.ExitCase 6 | import arrow.fx.typeclasses.ExitCase.Companion 7 | import arrow.typeclasses.Eq 8 | import kotlin.Boolean 9 | import kotlin.Deprecated 10 | import kotlin.Suppress 11 | import kotlin.jvm.JvmName 12 | 13 | @JvmName("neqv") 14 | @Suppress( 15 | "UNCHECKED_CAST", 16 | "USELESS_CAST", 17 | "EXTENSION_SHADOWED_BY_MEMBER", 18 | "UNUSED_PARAMETER" 19 | ) 20 | @Deprecated(IODeprecation) 21 | fun ExitCase.neqv(EQE: Eq, arg1: ExitCase): Boolean = 22 | arrow.fx.typeclasses.ExitCase.eq(EQE).run { 23 | this@neqv.neqv(arg1) as kotlin.Boolean 24 | } 25 | 26 | @Suppress( 27 | "UNCHECKED_CAST", 28 | "NOTHING_TO_INLINE" 29 | ) 30 | @Deprecated(IODeprecation) 31 | inline fun Companion.eq(EQE: Eq): ExitCaseEq = object : arrow.fx.extensions.ExitCaseEq 32 | { override fun EQE(): arrow.typeclasses.Eq = EQE } 33 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/extensions/io/dispatchers/IODispatchers.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.extensions.io.dispatchers 2 | 3 | import arrow.fx.IO.Companion 4 | import arrow.fx.IODeprecation 5 | import arrow.fx.extensions.IODispatchers 6 | import kotlin.Deprecated 7 | import kotlin.PublishedApi 8 | import kotlin.Suppress 9 | import kotlin.coroutines.CoroutineContext 10 | import kotlin.jvm.JvmName 11 | 12 | /** 13 | * cached extension 14 | */ 15 | @PublishedApi() 16 | internal val dispatchers_singleton: IODispatchers = object : arrow.fx.extensions.IODispatchers {} 17 | 18 | @JvmName("io") 19 | @Suppress( 20 | "UNCHECKED_CAST", 21 | "USELESS_CAST", 22 | "EXTENSION_SHADOWED_BY_MEMBER", 23 | "UNUSED_PARAMETER" 24 | ) 25 | @Deprecated(IODeprecation) 26 | fun io(): CoroutineContext = arrow.fx.IO 27 | .dispatchers() 28 | .io() as kotlin.coroutines.CoroutineContext 29 | 30 | @Suppress( 31 | "UNCHECKED_CAST", 32 | "NOTHING_TO_INLINE" 33 | ) 34 | @Deprecated(IODeprecation) 35 | inline fun Companion.dispatchers(): IODispatchers = dispatchers_singleton 36 | -------------------------------------------------------------------------------- /arrow-fx/src/test/kotlin/arrow/fx/data/DurationTest.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.data 2 | 3 | import arrow.core.test.UnitSpec 4 | import arrow.core.test.laws.HashLaws 5 | import arrow.core.test.laws.OrderLaws 6 | import arrow.core.test.laws.equalUnderTheLaw 7 | import arrow.fx.extensions.duration.eq.eq 8 | import arrow.fx.extensions.duration.hash.hash 9 | import arrow.fx.extensions.duration.order.order 10 | import arrow.fx.test.generators.duration 11 | import arrow.fx.typeclasses.Duration 12 | import io.kotlintest.properties.forAll 13 | 14 | class DurationTest : UnitSpec() { 15 | 16 | init { 17 | testLaws( 18 | OrderLaws.laws(Duration.order(), duration()), 19 | HashLaws.laws(Duration.hash(), duration(), Duration.eq()) 20 | // This fails on overflows on the associativity law 21 | // MonoidLaws.laws(Duration.monoid(), duration(), Duration.eq()) 22 | ) 23 | 24 | "plus is commutative" { 25 | forAll(duration(), duration()) { a, b -> 26 | (a + b).equalUnderTheLaw(b + a, Duration.eq()) 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/src/jmh/kotlin/arrow/benchmarks/Uncancellable.kt: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks 2 | 3 | import arrow.fx.IO 4 | import org.openjdk.jmh.annotations.Benchmark 5 | import org.openjdk.jmh.annotations.CompilerControl 6 | import org.openjdk.jmh.annotations.Fork 7 | import org.openjdk.jmh.annotations.Measurement 8 | import org.openjdk.jmh.annotations.Param 9 | import org.openjdk.jmh.annotations.Scope 10 | import org.openjdk.jmh.annotations.State 11 | import org.openjdk.jmh.annotations.Warmup 12 | import java.util.concurrent.TimeUnit 13 | 14 | @State(Scope.Thread) 15 | @Fork(2) 16 | @Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS) 17 | @Measurement(iterations = 10) 18 | @CompilerControl(CompilerControl.Mode.DONT_INLINE) 19 | open class Uncancellable { 20 | 21 | @Param("100") 22 | var size: Int = 0 23 | 24 | fun ioUncancellableLoop(i: Int): IO = 25 | if (i < size) IO { i + 1 }.uncancellable().flatMap { ioUncancellableLoop(it) } 26 | else IO.just(i) 27 | 28 | @Benchmark 29 | fun io(): Int = ioUncancellableLoop(0).unsafeRunSync() 30 | } 31 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/extensions/duration/eq/DurationEq.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.extensions.duration.eq 2 | 3 | import arrow.fx.IODeprecation 4 | import arrow.fx.extensions.DurationEq 5 | import arrow.fx.typeclasses.Duration 6 | import arrow.fx.typeclasses.Duration.Companion 7 | import kotlin.Boolean 8 | import kotlin.Deprecated 9 | import kotlin.PublishedApi 10 | import kotlin.Suppress 11 | import kotlin.jvm.JvmName 12 | 13 | /** 14 | * cached extension 15 | */ 16 | @PublishedApi() 17 | internal val eq_singleton: DurationEq = object : arrow.fx.extensions.DurationEq {} 18 | 19 | @JvmName("neqv") 20 | @Suppress( 21 | "UNCHECKED_CAST", 22 | "USELESS_CAST", 23 | "EXTENSION_SHADOWED_BY_MEMBER", 24 | "UNUSED_PARAMETER" 25 | ) 26 | @Deprecated(IODeprecation) 27 | fun Duration.neqv(arg1: Duration): Boolean = arrow.fx.typeclasses.Duration.eq().run { 28 | this@neqv.neqv(arg1) as kotlin.Boolean 29 | } 30 | 31 | @Suppress( 32 | "UNCHECKED_CAST", 33 | "NOTHING_TO_INLINE" 34 | ) 35 | @Deprecated(IODeprecation) 36 | inline fun Companion.eq(): DurationEq = eq_singleton 37 | -------------------------------------------------------------------------------- /arrow-fx/src/test/kotlin/arrow/fx/FiberTest.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx 2 | 3 | import arrow.core.extensions.monoid 4 | import arrow.core.test.laws.ApplicativeLaws 5 | import arrow.core.test.laws.MonoidLaws 6 | import arrow.fx.extensions.applicative 7 | import arrow.fx.extensions.functor 8 | import arrow.fx.extensions.io.applicative.applicative 9 | import arrow.fx.extensions.io.concurrent.concurrent 10 | import arrow.fx.extensions.monoid 11 | import arrow.fx.typeclasses.Fiber 12 | import arrow.fx.test.eq.eq 13 | import arrow.fx.test.eq.eqK 14 | import arrow.fx.test.generators.genK 15 | import io.kotlintest.properties.Gen 16 | 17 | class FiberTest : ArrowFxSpec() { 18 | 19 | init { 20 | testLaws( 21 | ApplicativeLaws.laws(Fiber.applicative(IO.concurrent()), Fiber.functor(IO.concurrent()), Fiber.genK(IO.applicative()), Fiber.eqK()), 22 | MonoidLaws.laws( 23 | Fiber.monoid(IO.concurrent(), Int.monoid()), 24 | Gen.int().map { i -> 25 | Fiber(IO.just(i), IO.unit) 26 | }, 27 | Fiber.eq(IO.eq()) 28 | ) 29 | ) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/src/jmh/kotlin/arrow/benchmarks/Defer.kt: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks 2 | 3 | import arrow.fx.IO 4 | import org.openjdk.jmh.annotations.Benchmark 5 | import org.openjdk.jmh.annotations.CompilerControl 6 | import org.openjdk.jmh.annotations.Fork 7 | import org.openjdk.jmh.annotations.Measurement 8 | import org.openjdk.jmh.annotations.Param 9 | import org.openjdk.jmh.annotations.Scope 10 | import org.openjdk.jmh.annotations.State 11 | import org.openjdk.jmh.annotations.Warmup 12 | import java.util.concurrent.TimeUnit 13 | 14 | @State(Scope.Thread) 15 | @Fork(2) 16 | @Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS) 17 | @Measurement(iterations = 10) 18 | @CompilerControl(CompilerControl.Mode.DONT_INLINE) 19 | open class Defer { 20 | 21 | @Param("3000") 22 | var size: Int = 0 23 | 24 | private fun ioDeferLoop(i: Int): IO = 25 | IO.defer { IO.just(i) }.flatMap { j -> 26 | if (j > size) IO.defer { IO.just(j) } else ioDeferLoop(j + 1) 27 | } 28 | 29 | @Benchmark 30 | fun io(): Int = 31 | ioDeferLoop(0).unsafeRunSync() 32 | } 33 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/extensions/io/monadThrow/IOMonadThrow.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.extensions.io.monadThrow 2 | 3 | import arrow.fx.IO 4 | import arrow.fx.IO.Companion 5 | import arrow.fx.IODeprecation 6 | import arrow.fx.extensions.IOMonadThrow 7 | import kotlin.Deprecated 8 | import kotlin.PublishedApi 9 | import kotlin.Suppress 10 | import kotlin.Throwable 11 | import kotlin.jvm.JvmName 12 | 13 | /** 14 | * cached extension 15 | */ 16 | @PublishedApi() 17 | internal val monadThrow_singleton: IOMonadThrow = object : arrow.fx.extensions.IOMonadThrow {} 18 | 19 | @JvmName("raiseNonFatal") 20 | @Suppress( 21 | "UNCHECKED_CAST", 22 | "USELESS_CAST", 23 | "EXTENSION_SHADOWED_BY_MEMBER", 24 | "UNUSED_PARAMETER" 25 | ) 26 | @Deprecated(IODeprecation) 27 | fun Throwable.raiseNonFatal(): IO = arrow.fx.IO.monadThrow().run { 28 | this@raiseNonFatal.raiseNonFatal() as arrow.fx.IO 29 | } 30 | 31 | @Suppress( 32 | "UNCHECKED_CAST", 33 | "NOTHING_TO_INLINE" 34 | ) 35 | @Deprecated(IODeprecation) 36 | inline fun Companion.monadThrow(): IOMonadThrow = monadThrow_singleton 37 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/extensions/duration/hash/DurationHash.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.extensions.duration.hash 2 | 3 | import arrow.fx.IODeprecation 4 | import arrow.fx.extensions.DurationHash 5 | import arrow.fx.typeclasses.Duration 6 | import arrow.fx.typeclasses.Duration.Companion 7 | import kotlin.Deprecated 8 | import kotlin.Int 9 | import kotlin.PublishedApi 10 | import kotlin.Suppress 11 | import kotlin.jvm.JvmName 12 | 13 | /** 14 | * cached extension 15 | */ 16 | @PublishedApi() 17 | internal val hash_singleton: DurationHash = object : arrow.fx.extensions.DurationHash {} 18 | 19 | @JvmName("hashWithSalt") 20 | @Suppress( 21 | "UNCHECKED_CAST", 22 | "USELESS_CAST", 23 | "EXTENSION_SHADOWED_BY_MEMBER", 24 | "UNUSED_PARAMETER" 25 | ) 26 | @Deprecated(IODeprecation) 27 | fun Duration.hashWithSalt(arg1: Int): Int = arrow.fx.typeclasses.Duration.hash().run { 28 | this@hashWithSalt.hashWithSalt(arg1) as kotlin.Int 29 | } 30 | 31 | @Suppress( 32 | "UNCHECKED_CAST", 33 | "NOTHING_TO_INLINE" 34 | ) 35 | @Deprecated(IODeprecation) 36 | inline fun Companion.hash(): DurationHash = hash_singleton 37 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/extensions/io/environment/IOEnvironment.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.extensions.io.environment 2 | 3 | import arrow.fx.ForIO 4 | import arrow.fx.IO.Companion 5 | import arrow.fx.IODeprecation 6 | import arrow.fx.extensions.IOEnvironment 7 | import arrow.fx.typeclasses.Dispatchers 8 | import kotlin.Deprecated 9 | import kotlin.PublishedApi 10 | import kotlin.Suppress 11 | import kotlin.jvm.JvmName 12 | 13 | /** 14 | * cached extension 15 | */ 16 | @PublishedApi() 17 | internal val environment_singleton: IOEnvironment = object : arrow.fx.extensions.IOEnvironment {} 18 | 19 | @JvmName("dispatchers") 20 | @Suppress( 21 | "UNCHECKED_CAST", 22 | "USELESS_CAST", 23 | "EXTENSION_SHADOWED_BY_MEMBER", 24 | "UNUSED_PARAMETER" 25 | ) 26 | @Deprecated(IODeprecation) 27 | fun dispatchers(): Dispatchers = arrow.fx.IO 28 | .environment() 29 | .dispatchers() as arrow.fx.typeclasses.Dispatchers 30 | 31 | @Suppress( 32 | "UNCHECKED_CAST", 33 | "NOTHING_TO_INLINE" 34 | ) 35 | @Deprecated(IODeprecation) 36 | inline fun Companion.environment(): IOEnvironment = environment_singleton 37 | -------------------------------------------------------------------------------- /.github/workflows/build_doc_arrow-fx.yml: -------------------------------------------------------------------------------- 1 | name: "arrow-fx: build documentation" 2 | 3 | on: pull_request 4 | 5 | jobs: 6 | arrow-fx_build_documentation: 7 | 8 | env: 9 | BASEDIR: ${{github.workspace}}/.. 10 | JAVA_OPTS: -Xms512m -Xmx1024m 11 | ARROW_LIB: arrow-fx 12 | 13 | runs-on: macos-latest 14 | timeout-minutes: 90 15 | 16 | steps: 17 | - uses: actions/checkout@v2 18 | - name: Checkout orchestrator 19 | env: 20 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 21 | run: | 22 | BRANCH_NAME=${{ github.event.pull_request.head.ref }} 23 | git clone https://github.com/arrow-kt/arrow.git $BASEDIR/arrow --depth 1 --no-single-branch 24 | . $BASEDIR/arrow/scripts/commons4gradle.sh 25 | updateOrchestrator $BRANCH_NAME 26 | - name: Install 27 | env: 28 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 29 | run: | 30 | BRANCH_NAME=${{ github.event.pull_request.head.ref }} 31 | $BASEDIR/arrow/scripts/action-install.sh $ARROW_LIB $BRANCH_NAME 32 | - name: Generate API doc and validate 33 | run: ./gradlew buildArrowDoc 34 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/typeclasses/ConcurrentContinuation.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.typeclasses 2 | 3 | import arrow.Kind 4 | import arrow.fx.IODeprecation 5 | import arrow.fx.MVar 6 | import arrow.fx.Promise 7 | import arrow.fx.Semaphore 8 | import kotlin.coroutines.CoroutineContext 9 | import kotlin.coroutines.EmptyCoroutineContext 10 | import kotlin.coroutines.RestrictsSuspension 11 | 12 | @RestrictsSuspension 13 | @Deprecated(IODeprecation) 14 | interface ConcurrentSyntax : Concurrent, AsyncSyntax 15 | 16 | @Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE") 17 | @Deprecated(IODeprecation) 18 | open class ConcurrentContinuation(private val CF: Concurrent, override val context: CoroutineContext = EmptyCoroutineContext) : 19 | AsyncContinuation(CF), Concurrent by CF, ConcurrentSyntax { 20 | override val fx: ConcurrentFx = CF.fx 21 | override fun Promise(): Kind> = CF.Promise() 22 | override fun MVar(): Kind> = CF.MVar() 23 | override fun MVar(a: A): Kind> = CF.MVar(a) 24 | override fun Semaphore(n: Long): Kind> = CF.Semaphore(n) 25 | } 26 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-scala-benchmarks/src/main/scala/zio/MapStream.scala: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks.effects.scala.zio 2 | 3 | import zio.Task 4 | 5 | object MapStream { 6 | 7 | def test(times: Int, batchSize: Int): Long = { 8 | var stream = range(0, times) 9 | var i = 0 10 | while (i < batchSize) { 11 | stream = mapStream(addOne)(stream) 12 | i += 1 13 | } 14 | 15 | ZIORTS.unsafeRun(sum(0)(stream)) 16 | } 17 | 18 | final case class Stream(value: Int, next: Task[Option[Stream]]) 19 | 20 | val addOne = (x: Int) => x + 1 21 | 22 | def range(from: Int, until: Int): Option[Stream] = 23 | if (from < until) Some(Stream(from, Task(range(from + 1, until)))) 24 | else None 25 | 26 | def mapStream(f: Int => Int)(box: Option[Stream]): Option[Stream] = 27 | box match { 28 | case Some(Stream(value, next)) => Some(Stream(f(value), next.map(mapStream(f)))) 29 | case None => None 30 | } 31 | 32 | def sum(acc: Long)(box: Option[Stream]): Task[Long] = 33 | box match { 34 | case Some(Stream(value, next)) => next.flatMap(sum(acc + value)) 35 | case None => Task.succeed(acc) 36 | } 37 | 38 | 39 | } -------------------------------------------------------------------------------- /arrow-benchmarks-fx/src/jmh/kotlin/arrow/benchmarks/ParMap.kt: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks 2 | 3 | import arrow.core.extensions.list.foldable.foldLeft 4 | import arrow.fx.IO 5 | import arrow.fx.IODispatchers 6 | import org.openjdk.jmh.annotations.Benchmark 7 | import org.openjdk.jmh.annotations.CompilerControl 8 | import org.openjdk.jmh.annotations.Fork 9 | import org.openjdk.jmh.annotations.Measurement 10 | import org.openjdk.jmh.annotations.Param 11 | import org.openjdk.jmh.annotations.Scope 12 | import org.openjdk.jmh.annotations.State 13 | import org.openjdk.jmh.annotations.Warmup 14 | import java.util.concurrent.TimeUnit 15 | 16 | @State(Scope.Thread) 17 | @Fork(2) 18 | @Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS) 19 | @Measurement(iterations = 10) 20 | @CompilerControl(CompilerControl.Mode.DONT_INLINE) 21 | open class ParMap { 22 | 23 | @Param("100") 24 | var size: Int = 0 25 | 26 | private fun ioHelper(): IO = 27 | (0 until size).toList().foldLeft(IO { 0 }) { acc, i -> 28 | IO.parMapN(IODispatchers.CommonPool, acc, IO { i }) { (a, b) -> a + b } 29 | } 30 | 31 | @Benchmark 32 | fun io(): Int = 33 | ioHelper().unsafeRunSync() 34 | } 35 | -------------------------------------------------------------------------------- /arrow-fx-rx2/src/main/kotlin/arrow/fx/rx2/extensions/maybek/monadThrow/MaybeKMonadThrow.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.rx2.extensions.maybek.monadThrow 2 | 3 | import arrow.fx.rx2.DeprecateRxJava 4 | import arrow.fx.rx2.MaybeK 5 | import arrow.fx.rx2.MaybeK.Companion 6 | import arrow.fx.rx2.extensions.MaybeKMonadThrow 7 | import kotlin.Deprecated 8 | import kotlin.PublishedApi 9 | import kotlin.Suppress 10 | import kotlin.Throwable 11 | import kotlin.jvm.JvmName 12 | 13 | /** 14 | * cached extension 15 | */ 16 | @PublishedApi() 17 | internal val monadThrow_singleton: MaybeKMonadThrow = object : 18 | arrow.fx.rx2.extensions.MaybeKMonadThrow {} 19 | 20 | @JvmName("raiseNonFatal") 21 | @Suppress( 22 | "UNCHECKED_CAST", 23 | "USELESS_CAST", 24 | "EXTENSION_SHADOWED_BY_MEMBER", 25 | "UNUSED_PARAMETER" 26 | ) 27 | @Deprecated(DeprecateRxJava) 28 | fun Throwable.raiseNonFatal(): MaybeK = arrow.fx.rx2.MaybeK.monadThrow().run { 29 | this@raiseNonFatal.raiseNonFatal() as arrow.fx.rx2.MaybeK 30 | } 31 | 32 | @Suppress( 33 | "UNCHECKED_CAST", 34 | "NOTHING_TO_INLINE" 35 | ) 36 | @Deprecated(DeprecateRxJava) 37 | inline fun Companion.monadThrow(): MaybeKMonadThrow = monadThrow_singleton 38 | -------------------------------------------------------------------------------- /arrow-fx-rx2/src/main/kotlin/arrow/fx/rx2/extensions/singlek/monadThrow/SingleKMonadThrow.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.rx2.extensions.singlek.monadThrow 2 | 3 | import arrow.fx.rx2.DeprecateRxJava 4 | import arrow.fx.rx2.SingleK 5 | import arrow.fx.rx2.SingleK.Companion 6 | import arrow.fx.rx2.extensions.SingleKMonadThrow 7 | import kotlin.Deprecated 8 | import kotlin.PublishedApi 9 | import kotlin.Suppress 10 | import kotlin.Throwable 11 | import kotlin.jvm.JvmName 12 | 13 | /** 14 | * cached extension 15 | */ 16 | @PublishedApi() 17 | internal val monadThrow_singleton: SingleKMonadThrow = object : 18 | arrow.fx.rx2.extensions.SingleKMonadThrow {} 19 | 20 | @JvmName("raiseNonFatal") 21 | @Suppress( 22 | "UNCHECKED_CAST", 23 | "USELESS_CAST", 24 | "EXTENSION_SHADOWED_BY_MEMBER", 25 | "UNUSED_PARAMETER" 26 | ) 27 | @Deprecated(DeprecateRxJava) 28 | fun Throwable.raiseNonFatal(): SingleK = arrow.fx.rx2.SingleK.monadThrow().run { 29 | this@raiseNonFatal.raiseNonFatal() as arrow.fx.rx2.SingleK 30 | } 31 | 32 | @Suppress( 33 | "UNCHECKED_CAST", 34 | "NOTHING_TO_INLINE" 35 | ) 36 | @Deprecated(DeprecateRxJava) 37 | inline fun Companion.monadThrow(): SingleKMonadThrow = monadThrow_singleton 38 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/extensions/invariant/QueueInvariant.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.extensions.invariant 2 | 3 | import arrow.Kind 4 | import arrow.fx.ForQueue 5 | import arrow.fx.IODeprecation 6 | import arrow.fx.Queue 7 | import arrow.fx.Queue.Companion 8 | import arrow.fx.extensions.QueueInvariant 9 | import arrow.typeclasses.Functor 10 | import kotlin.Deprecated 11 | import kotlin.Function1 12 | import kotlin.Suppress 13 | import kotlin.jvm.JvmName 14 | 15 | @JvmName("imap") 16 | @Suppress( 17 | "UNCHECKED_CAST", 18 | "USELESS_CAST", 19 | "EXTENSION_SHADOWED_BY_MEMBER", 20 | "UNUSED_PARAMETER" 21 | ) 22 | @Deprecated(IODeprecation) 23 | fun Kind, A>.imap( 24 | FR: Functor, 25 | arg1: Function1, 26 | arg2: Function1 27 | ): Queue = arrow.fx.Queue.invariant(FR).run { 28 | this@imap.imap(arg1, arg2) as arrow.fx.Queue 29 | } 30 | 31 | @Suppress( 32 | "UNCHECKED_CAST", 33 | "NOTHING_TO_INLINE" 34 | ) 35 | @Deprecated(IODeprecation) 36 | inline fun Companion.invariant(FR: Functor): QueueInvariant = object : 37 | arrow.fx.extensions.QueueInvariant { override fun FR(): arrow.typeclasses.Functor = FR } 38 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/src/jmh/kotlin/arrow/benchmarks/ForkFiber.kt: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks 2 | 3 | import arrow.fx.IO 4 | import arrow.fx.IODispatchers 5 | import arrow.fx.fix 6 | import org.openjdk.jmh.annotations.Benchmark 7 | import org.openjdk.jmh.annotations.CompilerControl 8 | import org.openjdk.jmh.annotations.Fork 9 | import org.openjdk.jmh.annotations.Measurement 10 | import org.openjdk.jmh.annotations.Param 11 | import org.openjdk.jmh.annotations.Scope 12 | import org.openjdk.jmh.annotations.State 13 | import org.openjdk.jmh.annotations.Warmup 14 | import java.util.concurrent.TimeUnit 15 | 16 | @State(Scope.Thread) 17 | @Fork(2) 18 | @Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS) 19 | @Measurement(iterations = 10) 20 | @CompilerControl(CompilerControl.Mode.DONT_INLINE) 21 | open class ForkFiber { 22 | 23 | @Param("100") 24 | var size: Int = 0 25 | 26 | private fun ioStartLoop(i: Int): IO = 27 | if (i < size) { 28 | IO { i + 1 }.fork(IODispatchers.CommonPool).flatMap { fiber -> 29 | fiber.join().fix().flatMap { ioStartLoop(it) } 30 | } 31 | } else IO.just(i) 32 | 33 | @Benchmark 34 | fun io(): Int = 35 | ioStartLoop(0).unsafeRunSync() 36 | } 37 | -------------------------------------------------------------------------------- /arrow-fx/src/test/kotlin/arrow/fx/predef.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx 2 | 3 | import kotlinx.atomicfu.atomic 4 | import java.util.concurrent.ExecutorService 5 | import java.util.concurrent.SynchronousQueue 6 | import java.util.concurrent.ThreadFactory 7 | import java.util.concurrent.ThreadPoolExecutor 8 | import java.util.concurrent.TimeUnit 9 | 10 | /** 11 | * This [ExecutorService] doesn't keep any Thread alive, so the maximumPoolSize should be equal to the # of scheduled tasks. 12 | * 13 | * Only useful for very specific task that want to keep track of how many times [kotlin.coroutines.startCoroutine] is called etc, 14 | * it also names every thread differently so you can rely on the names to check if tasks where scheduled on different Threads. 15 | */ 16 | internal fun newCountingThreadFactory(name: String, maximumPoolSize: Int = 0): ExecutorService = 17 | ThreadPoolExecutor(0, maximumPoolSize, 0, TimeUnit.MILLISECONDS, SynchronousQueue(), CountingThreadFactory(name)) 18 | 19 | private class CountingThreadFactory(val name: String) : ThreadFactory { 20 | private val counter = atomic(0) 21 | override fun newThread(r: Runnable): Thread = 22 | Thread(r, "$name-${counter.getAndIncrement()}") 23 | } 24 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/src/jmh/kotlin/arrow/benchmarks/HandleNonRaised.kt: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks 2 | 3 | import arrow.fx.IO 4 | import org.openjdk.jmh.annotations.Benchmark 5 | import org.openjdk.jmh.annotations.CompilerControl 6 | import org.openjdk.jmh.annotations.Fork 7 | import org.openjdk.jmh.annotations.Measurement 8 | import org.openjdk.jmh.annotations.Param 9 | import org.openjdk.jmh.annotations.Scope 10 | import org.openjdk.jmh.annotations.State 11 | import org.openjdk.jmh.annotations.Warmup 12 | import java.util.concurrent.TimeUnit 13 | import arrow.fx.handleErrorWith as ioHandleErrorWith 14 | 15 | @State(Scope.Thread) 16 | @Fork(2) 17 | @Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS) 18 | @Measurement(iterations = 10) 19 | @CompilerControl(CompilerControl.Mode.DONT_INLINE) 20 | open class HandleNonRaised { 21 | 22 | @Param("10000") 23 | var size: Int = 0 24 | 25 | private fun ioHappyPathLoop(i: Int): IO = 26 | if (i < size) 27 | IO.just(i + 1) 28 | .ioHandleErrorWith { IO.raiseError(it) } 29 | .flatMap { ioHappyPathLoop(it) } 30 | else 31 | IO.just(i) 32 | 33 | @Benchmark 34 | fun io(): Int = 35 | ioHappyPathLoop(0).unsafeRunSync() 36 | } 37 | -------------------------------------------------------------------------------- /arrow-fx-reactor/src/main/kotlin/arrow/fx/reactor/extensions/fluxk/monadThrow/FluxKMonadThrow.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.reactor.extensions.fluxk.monadThrow 2 | 3 | import arrow.fx.reactor.DeprecateReactor 4 | import arrow.fx.reactor.FluxK 5 | import arrow.fx.reactor.FluxK.Companion 6 | import arrow.fx.reactor.extensions.FluxKMonadThrow 7 | import kotlin.Deprecated 8 | import kotlin.PublishedApi 9 | import kotlin.Suppress 10 | import kotlin.Throwable 11 | import kotlin.jvm.JvmName 12 | 13 | /** 14 | * cached extension 15 | */ 16 | @PublishedApi() 17 | internal val monadThrow_singleton: FluxKMonadThrow = object : 18 | arrow.fx.reactor.extensions.FluxKMonadThrow {} 19 | 20 | @JvmName("raiseNonFatal") 21 | @Suppress( 22 | "UNCHECKED_CAST", 23 | "USELESS_CAST", 24 | "EXTENSION_SHADOWED_BY_MEMBER", 25 | "UNUSED_PARAMETER" 26 | ) 27 | @Deprecated(DeprecateReactor) 28 | fun Throwable.raiseNonFatal(): FluxK = arrow.fx.reactor.FluxK.monadThrow().run { 29 | this@raiseNonFatal.raiseNonFatal() as arrow.fx.reactor.FluxK 30 | } 31 | 32 | @Suppress( 33 | "UNCHECKED_CAST", 34 | "NOTHING_TO_INLINE" 35 | ) 36 | @Deprecated(DeprecateReactor) 37 | inline fun Companion.monadThrow(): FluxKMonadThrow = monadThrow_singleton 38 | -------------------------------------------------------------------------------- /arrow-fx-reactor/src/main/kotlin/arrow/fx/reactor/extensions/monok/monadThrow/MonoKMonadThrow.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.reactor.extensions.monok.monadThrow 2 | 3 | import arrow.fx.reactor.DeprecateReactor 4 | import arrow.fx.reactor.MonoK 5 | import arrow.fx.reactor.MonoK.Companion 6 | import arrow.fx.reactor.extensions.MonoKMonadThrow 7 | import kotlin.Deprecated 8 | import kotlin.PublishedApi 9 | import kotlin.Suppress 10 | import kotlin.Throwable 11 | import kotlin.jvm.JvmName 12 | 13 | /** 14 | * cached extension 15 | */ 16 | @PublishedApi() 17 | internal val monadThrow_singleton: MonoKMonadThrow = object : 18 | arrow.fx.reactor.extensions.MonoKMonadThrow {} 19 | 20 | @JvmName("raiseNonFatal") 21 | @Suppress( 22 | "UNCHECKED_CAST", 23 | "USELESS_CAST", 24 | "EXTENSION_SHADOWED_BY_MEMBER", 25 | "UNUSED_PARAMETER" 26 | ) 27 | @Deprecated(DeprecateReactor) 28 | fun Throwable.raiseNonFatal(): MonoK = arrow.fx.reactor.MonoK.monadThrow().run { 29 | this@raiseNonFatal.raiseNonFatal() as arrow.fx.reactor.MonoK 30 | } 31 | 32 | @Suppress( 33 | "UNCHECKED_CAST", 34 | "NOTHING_TO_INLINE" 35 | ) 36 | @Deprecated(DeprecateReactor) 37 | inline fun Companion.monadThrow(): MonoKMonadThrow = monadThrow_singleton 38 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-scala-benchmarks/src/main/scala/cats/MapStream.scala: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks.effects.scala.cats 2 | 3 | import cats.effect.IO 4 | 5 | object MapStream { 6 | 7 | def test(times: Int, batchSize: Int): Long = { 8 | var stream = range(0, times) 9 | var i = 0 10 | while (i < batchSize) { 11 | stream = mapStream(addOne)(stream) 12 | i += 1 13 | } 14 | sum(0)(stream).unsafeRunSync() 15 | } 16 | 17 | final case class Stream(value: Int, next: IO[Option[Stream]]) 18 | 19 | val addOne = (x: Int) => x + 1 20 | 21 | def range(from: Int, until: Int): Option[Stream] = 22 | if (from < until) 23 | Some(Stream(from, IO(range(from + 1, until)))) 24 | else 25 | None 26 | 27 | def mapStream(f: Int => Int)(box: Option[Stream]): Option[Stream] = 28 | box match { 29 | case Some(Stream(value, next)) => 30 | Some(Stream(f(value), next.map(mapStream(f)))) 31 | case None => 32 | None 33 | } 34 | 35 | def sum(acc: Long)(box: Option[Stream]): IO[Long] = 36 | box match { 37 | case Some(Stream(value, next)) => 38 | next.flatMap(sum(acc + value)) 39 | case None => 40 | IO.pure(acc) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /arrow-fx-rx2/src/main/kotlin/arrow/fx/rx2/extensions/flowablek/monadThrow/FlowableKMonadThrow.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.rx2.extensions.flowablek.monadThrow 2 | 3 | import arrow.fx.rx2.DeprecateRxJava 4 | import arrow.fx.rx2.FlowableK 5 | import arrow.fx.rx2.FlowableK.Companion 6 | import arrow.fx.rx2.extensions.FlowableKMonadThrow 7 | import kotlin.Deprecated 8 | import kotlin.PublishedApi 9 | import kotlin.Suppress 10 | import kotlin.Throwable 11 | import kotlin.jvm.JvmName 12 | 13 | /** 14 | * cached extension 15 | */ 16 | @PublishedApi() 17 | internal val monadThrow_singleton: FlowableKMonadThrow = object : 18 | arrow.fx.rx2.extensions.FlowableKMonadThrow {} 19 | 20 | @JvmName("raiseNonFatal") 21 | @Suppress( 22 | "UNCHECKED_CAST", 23 | "USELESS_CAST", 24 | "EXTENSION_SHADOWED_BY_MEMBER", 25 | "UNUSED_PARAMETER" 26 | ) 27 | @Deprecated(DeprecateRxJava) 28 | fun Throwable.raiseNonFatal(): FlowableK = arrow.fx.rx2.FlowableK.monadThrow().run { 29 | this@raiseNonFatal.raiseNonFatal() as arrow.fx.rx2.FlowableK 30 | } 31 | 32 | @Suppress( 33 | "UNCHECKED_CAST", 34 | "NOTHING_TO_INLINE" 35 | ) 36 | @Deprecated(DeprecateRxJava) 37 | inline fun Companion.monadThrow(): FlowableKMonadThrow = monadThrow_singleton 38 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/extensions/duration.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.extensions 2 | 3 | import arrow.core.Ordering 4 | import arrow.fx.IODeprecation 5 | import arrow.fx.typeclasses.Duration 6 | import arrow.fx.typeclasses.seconds 7 | import arrow.typeclasses.Eq 8 | import arrow.typeclasses.Hash 9 | import arrow.typeclasses.Monoid 10 | import arrow.typeclasses.Order 11 | import arrow.typeclasses.Semigroup 12 | 13 | @Deprecated(IODeprecation) 14 | interface DurationEq : Eq { 15 | override fun Duration.eqv(b: Duration): Boolean = compareTo(b) == 0 16 | } 17 | 18 | @Deprecated(IODeprecation) 19 | interface DurationHash : Hash { 20 | override fun Duration.hash(): Int = hashCode() 21 | } 22 | 23 | @Deprecated(IODeprecation) 24 | interface DurationOrder : Order { 25 | override fun Duration.compare(b: Duration): Ordering = 26 | Ordering.fromInt(this.compareTo(b)) 27 | } 28 | 29 | @Deprecated(IODeprecation) 30 | interface DurationSemigroup : Semigroup { 31 | override fun Duration.combine(b: Duration): Duration = this + b 32 | } 33 | 34 | @Deprecated(IODeprecation) 35 | interface DurationMonoid : Monoid, DurationSemigroup { 36 | override fun empty(): Duration = 0.seconds 37 | } 38 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/extensions/io/effect/IOEffect.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.extensions.io.effect 2 | 3 | import arrow.Kind 4 | import arrow.core.Either 5 | import arrow.fx.ForIO 6 | import arrow.fx.IO 7 | import arrow.fx.IO.Companion 8 | import arrow.fx.IODeprecation 9 | import arrow.fx.extensions.IOEffect 10 | import kotlin.Deprecated 11 | import kotlin.Function1 12 | import kotlin.PublishedApi 13 | import kotlin.Suppress 14 | import kotlin.Throwable 15 | import kotlin.Unit 16 | import kotlin.jvm.JvmName 17 | 18 | /** 19 | * cached extension 20 | */ 21 | @PublishedApi() 22 | internal val effect_singleton: IOEffect = object : arrow.fx.extensions.IOEffect {} 23 | 24 | @JvmName("runAsync") 25 | @Suppress( 26 | "UNCHECKED_CAST", 27 | "USELESS_CAST", 28 | "EXTENSION_SHADOWED_BY_MEMBER", 29 | "UNUSED_PARAMETER" 30 | ) 31 | @Deprecated(IODeprecation) 32 | fun Kind.runAsync(cb: Function1, Kind>): IO = 33 | arrow.fx.IO.effect().run { 34 | this@runAsync.runAsync(cb) as arrow.fx.IO 35 | } 36 | 37 | @Suppress( 38 | "UNCHECKED_CAST", 39 | "NOTHING_TO_INLINE" 40 | ) 41 | @Deprecated(IODeprecation) 42 | inline fun Companion.effect(): IOEffect = effect_singleton 43 | -------------------------------------------------------------------------------- /arrow-fx-rx2/src/main/kotlin/arrow/fx/rx2/extensions/observablek/monadThrow/ObservableKMonadThrow.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.rx2.extensions.observablek.monadThrow 2 | 3 | import arrow.fx.rx2.DeprecateRxJava 4 | import arrow.fx.rx2.ObservableK 5 | import arrow.fx.rx2.ObservableK.Companion 6 | import arrow.fx.rx2.extensions.ObservableKMonadThrow 7 | import kotlin.Deprecated 8 | import kotlin.PublishedApi 9 | import kotlin.Suppress 10 | import kotlin.Throwable 11 | import kotlin.jvm.JvmName 12 | 13 | /** 14 | * cached extension 15 | */ 16 | @PublishedApi() 17 | internal val monadThrow_singleton: ObservableKMonadThrow = object : 18 | arrow.fx.rx2.extensions.ObservableKMonadThrow {} 19 | 20 | @JvmName("raiseNonFatal") 21 | @Suppress( 22 | "UNCHECKED_CAST", 23 | "USELESS_CAST", 24 | "EXTENSION_SHADOWED_BY_MEMBER", 25 | "UNUSED_PARAMETER" 26 | ) 27 | @Deprecated(DeprecateRxJava) 28 | fun Throwable.raiseNonFatal(): ObservableK = arrow.fx.rx2.ObservableK.monadThrow().run { 29 | this@raiseNonFatal.raiseNonFatal() as arrow.fx.rx2.ObservableK 30 | } 31 | 32 | @Suppress( 33 | "UNCHECKED_CAST", 34 | "NOTHING_TO_INLINE" 35 | ) 36 | @Deprecated(DeprecateRxJava) 37 | inline fun Companion.monadThrow(): ObservableKMonadThrow = monadThrow_singleton 38 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/src/jmh/kotlin/arrow/benchmarks/Bracket.kt: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks 2 | 3 | import arrow.fx.IO 4 | import arrow.unsafe 5 | import org.openjdk.jmh.annotations.Benchmark 6 | import org.openjdk.jmh.annotations.CompilerControl 7 | import org.openjdk.jmh.annotations.Fork 8 | import org.openjdk.jmh.annotations.Measurement 9 | import org.openjdk.jmh.annotations.Param 10 | import org.openjdk.jmh.annotations.Scope 11 | import org.openjdk.jmh.annotations.State 12 | import org.openjdk.jmh.annotations.Warmup 13 | import java.util.concurrent.TimeUnit 14 | import arrow.fx.extensions.io.unsafeRun.runBlocking as ioRunBlocking 15 | 16 | @State(Scope.Thread) 17 | @Fork(2) 18 | @Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS) 19 | @Measurement(iterations = 10) 20 | @CompilerControl(CompilerControl.Mode.DONT_INLINE) 21 | open class Bracket { 22 | 23 | @Param("100") 24 | var size: Int = 0 25 | 26 | private fun ioBracketLoop(i: Int): IO = 27 | if (i < size) 28 | IO.just(i).bracket({ IO.unit }, { ib -> IO { ib + 1 } }).flatMap { ioBracketLoop(it) } 29 | else 30 | IO.just(i) 31 | 32 | @Benchmark 33 | fun io() = 34 | unsafe { 35 | ioRunBlocking { 36 | ioBracketLoop(0) 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/extensions/resource/monadIO/ResourceMonadIO.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.extensions.resource.monadIO 2 | 3 | import arrow.fx.IO 4 | import arrow.fx.IODeprecation 5 | import arrow.fx.Resource 6 | import arrow.fx.Resource.Companion 7 | import arrow.fx.extensions.ResourceMonadIO 8 | import arrow.fx.typeclasses.Bracket 9 | import arrow.fx.typeclasses.MonadIO 10 | import kotlin.Deprecated 11 | import kotlin.Suppress 12 | import kotlin.jvm.JvmName 13 | 14 | @JvmName("liftIO") 15 | @Suppress( 16 | "UNCHECKED_CAST", 17 | "USELESS_CAST", 18 | "EXTENSION_SHADOWED_BY_MEMBER", 19 | "UNUSED_PARAMETER" 20 | ) 21 | @Deprecated(IODeprecation) 22 | fun IO.liftIO(FIO: MonadIO, BR: Bracket): Resource = 23 | arrow.fx.Resource.monadIO(FIO, BR).run { 24 | this@liftIO.liftIO() as arrow.fx.Resource 25 | } 26 | 27 | @Suppress( 28 | "UNCHECKED_CAST", 29 | "NOTHING_TO_INLINE" 30 | ) 31 | @Deprecated(IODeprecation) 32 | inline fun Companion.monadIO(FIO: MonadIO, BR: Bracket): ResourceMonadIO = 33 | object : arrow.fx.extensions.ResourceMonadIO { 34 | override fun FIO(): 35 | arrow.fx.typeclasses.MonadIO = FIO 36 | 37 | override fun BR(): arrow.fx.typeclasses.Bracket = BR 38 | } 39 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/arrow-kio-benchmarks/src/main/kotlin/kio/MapStream.kt: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks.effects.kio 2 | 3 | import it.msec.kio.Task 4 | import it.msec.kio.effect 5 | import it.msec.kio.flatMap 6 | import it.msec.kio.map 7 | import it.msec.kio.just 8 | import it.msec.kio.result.getOrThrow 9 | import it.msec.kio.runtime.Runtime.unsafeRunSync 10 | 11 | object MapStream { 12 | 13 | fun test(times: Int, batchSize: Int): Long { 14 | var stream = range(0, times) 15 | var i = 0 16 | while (i < batchSize) { 17 | stream = mapStream(addOne)(stream) 18 | i += 1 19 | } 20 | 21 | return unsafeRunSync(sum(0)(stream)).getOrThrow() 22 | } 23 | 24 | data class Stream(val value: Int, val next: Task) 25 | 26 | val addOne = { x: Int -> x + 1 } 27 | 28 | fun range(from: Int, until: Int): Stream? = 29 | if (from < until) 30 | Stream(from, effect { range(from + 1, until) }) 31 | else 32 | null 33 | 34 | fun mapStream(f: (Int) -> Int): (box: Stream?) -> Stream? = { box -> 35 | if (box != null) 36 | Stream(f(box.value), box.next.map(mapStream(f))) 37 | else 38 | null 39 | } 40 | 41 | fun sum(acc: Long): (Stream?) -> Task = { box -> 42 | box?.next?.flatMap(sum(acc + box.value)) ?: just(acc) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /arrow-docs/docs/landscape/fx-home-code.md: -------------------------------------------------------------------------------- 1 | ```kotlin:ank:playground 2 | import arrow.fx.coroutines.parTraverse 3 | import arrow.fx.coroutines.parMapN 4 | 5 | data class Street(val name: String) 6 | data class Company(val name: String) 7 | data class Employee(val name: String, val company: Company, val hired : Boolean = false) 8 | 9 | /** An async non blocking service **/ 10 | suspend fun company(name: String): Company = 11 | Company("$name on ${Thread.currentThread().name}") 12 | 13 | /** An async non blocking service **/ 14 | suspend fun street(name: String): Street = 15 | Street("$name on ${Thread.currentThread().name}") 16 | 17 | /** An async non blocking service **/ 18 | suspend fun hire(employee: Employee): Employee = 19 | employee.copy(hired = true) 20 | 21 | fun employee(name: String, company: Company): Employee = 22 | Employee(name, company) 23 | 24 | suspend fun main() { 25 | //sampleStart 26 | //maps each function to `::employee` in parallel 27 | val audrey = parMapN({ "Audrey" }, { company("Arrow") }, ::employee) 28 | val pepe = parMapN({ "Pepe" }, { company("Arrow") }, ::employee) 29 | val candidates = listOf(audrey, pepe) 30 | val employees = candidates.parTraverse(::hire) //hires in parallel 31 | //sampleEnd 32 | println(employees) 33 | } 34 | ``` 35 | -------------------------------------------------------------------------------- /arrow-docs/src/main/kotlin/SyntaxHelper.kt: -------------------------------------------------------------------------------- 1 | package com.example.domain 2 | 3 | import arrow.core.ListK 4 | import arrow.core.MapK 5 | import arrow.optics.optics 6 | 7 | @optics 8 | data class Street(val number: Int, val name: String) { 9 | companion object 10 | } 11 | 12 | @optics 13 | data class Address(val city: String, val street: Street) { 14 | companion object 15 | } 16 | 17 | @optics 18 | data class Company(val name: String, val address: Address) { 19 | companion object 20 | } 21 | 22 | @optics 23 | data class Employee(val name: String, val company: Company?) { 24 | companion object 25 | } 26 | 27 | @optics 28 | data class Employees(val employees: ListK) { 29 | companion object 30 | } 31 | 32 | @optics 33 | data class Db(val content: MapK) { 34 | companion object 35 | } 36 | 37 | @optics 38 | @Suppress("UtilityClassWithPublicConstructor") 39 | sealed class NetworkResult { 40 | companion object 41 | } 42 | 43 | @optics 44 | data class Success(val content: String) : NetworkResult() { 45 | companion object 46 | } 47 | 48 | @optics 49 | sealed class NetworkError : NetworkResult() { 50 | companion object 51 | } 52 | 53 | @optics 54 | data class HttpError(val message: String) : NetworkError() { 55 | companion object 56 | } 57 | 58 | object TimeoutError : NetworkError() 59 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/src/jmh/kotlin/arrow/benchmarks/Cancellable.kt: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks 2 | 3 | import arrow.core.Right 4 | import arrow.fx.IO 5 | import arrow.fx.extensions.io.concurrent.concurrent 6 | import arrow.fx.fix 7 | import org.openjdk.jmh.annotations.Benchmark 8 | import org.openjdk.jmh.annotations.CompilerControl 9 | import org.openjdk.jmh.annotations.Fork 10 | import org.openjdk.jmh.annotations.Measurement 11 | import org.openjdk.jmh.annotations.Param 12 | import org.openjdk.jmh.annotations.Scope 13 | import org.openjdk.jmh.annotations.State 14 | import org.openjdk.jmh.annotations.Warmup 15 | import java.util.concurrent.TimeUnit 16 | 17 | @State(Scope.Thread) 18 | @Fork(2) 19 | @Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS) 20 | @Measurement(iterations = 10) 21 | @CompilerControl(CompilerControl.Mode.DONT_INLINE) 22 | open class Cancellable { 23 | 24 | @Param("100") 25 | var size: Int = 0 26 | 27 | fun evalCancellable(n: Int): IO = 28 | IO.concurrent().cancellable { cb -> 29 | cb(Right(n)) 30 | IO.unit 31 | }.fix() 32 | 33 | fun cancellableLoop(i: Int): IO = 34 | if (i < size) evalCancellable(i + 1).flatMap { cancellableLoop(it) } 35 | else evalCancellable(i) 36 | 37 | @Benchmark 38 | fun io(): Int = 39 | cancellableLoop(0).unsafeRunSync() 40 | } 41 | -------------------------------------------------------------------------------- /arrow-fx-rx2/src/main/kotlin/arrow/fx/rx2/extensions/maybek/effect/MaybeKEffect.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.rx2.extensions.maybek.effect 2 | 3 | import arrow.Kind 4 | import arrow.core.Either 5 | import arrow.fx.rx2.DeprecateRxJava 6 | import arrow.fx.rx2.ForMaybeK 7 | import arrow.fx.rx2.MaybeK 8 | import arrow.fx.rx2.MaybeK.Companion 9 | import arrow.fx.rx2.extensions.MaybeKEffect 10 | import kotlin.Deprecated 11 | import kotlin.Function1 12 | import kotlin.PublishedApi 13 | import kotlin.Suppress 14 | import kotlin.Throwable 15 | import kotlin.Unit 16 | import kotlin.jvm.JvmName 17 | 18 | /** 19 | * cached extension 20 | */ 21 | @PublishedApi() 22 | internal val effect_singleton: MaybeKEffect = object : arrow.fx.rx2.extensions.MaybeKEffect {} 23 | 24 | @JvmName("runAsync") 25 | @Suppress( 26 | "UNCHECKED_CAST", 27 | "USELESS_CAST", 28 | "EXTENSION_SHADOWED_BY_MEMBER", 29 | "UNUSED_PARAMETER" 30 | ) 31 | @Deprecated(DeprecateRxJava) 32 | fun Kind.runAsync(arg1: Function1, Kind>): 33 | MaybeK = arrow.fx.rx2.MaybeK.effect().run { 34 | this@runAsync.runAsync(arg1) as arrow.fx.rx2.MaybeK 35 | } 36 | 37 | @Suppress( 38 | "UNCHECKED_CAST", 39 | "NOTHING_TO_INLINE" 40 | ) 41 | @Deprecated(DeprecateRxJava) 42 | inline fun Companion.effect(): MaybeKEffect = effect_singleton 43 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/src/jmh/kotlin/arrow/benchmarks/HandleRaisedError.kt: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks 2 | 3 | import arrow.fx.IO 4 | import org.openjdk.jmh.annotations.Benchmark 5 | import org.openjdk.jmh.annotations.CompilerControl 6 | import org.openjdk.jmh.annotations.Fork 7 | import org.openjdk.jmh.annotations.Measurement 8 | import org.openjdk.jmh.annotations.Param 9 | import org.openjdk.jmh.annotations.Scope 10 | import org.openjdk.jmh.annotations.State 11 | import org.openjdk.jmh.annotations.Warmup 12 | import java.util.concurrent.TimeUnit 13 | import arrow.fx.extensions.io.applicativeError.handleErrorWith as ioHandleError 14 | 15 | @State(Scope.Thread) 16 | @Fork(2) 17 | @Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS) 18 | @Measurement(iterations = 10) 19 | @CompilerControl(CompilerControl.Mode.DONT_INLINE) 20 | open class HandleRaisedError { 21 | 22 | @Param("10000") 23 | var size: Int = 0 24 | 25 | private val dummy = RuntimeException("dummy") 26 | 27 | private fun ioErrorRaisedloop(i: Int): IO = 28 | if (i < size) 29 | IO.raiseError(dummy) 30 | .flatMap { x -> IO.just(x + 1) } 31 | .flatMap { x -> IO.just(x + 1) } 32 | .ioHandleError { ioErrorRaisedloop(i + 1) } 33 | else 34 | IO.just(i) 35 | 36 | @Benchmark 37 | fun io(): Int = 38 | ioErrorRaisedloop(0).unsafeRunSync() 39 | } 40 | -------------------------------------------------------------------------------- /arrow-fx-rx2/src/main/kotlin/arrow/fx/rx2/extensions/singlek/effect/SingleKEffect.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.rx2.extensions.singlek.effect 2 | 3 | import arrow.Kind 4 | import arrow.core.Either 5 | import arrow.fx.rx2.DeprecateRxJava 6 | import arrow.fx.rx2.ForSingleK 7 | import arrow.fx.rx2.SingleK 8 | import arrow.fx.rx2.SingleK.Companion 9 | import arrow.fx.rx2.extensions.SingleKEffect 10 | import kotlin.Deprecated 11 | import kotlin.Function1 12 | import kotlin.PublishedApi 13 | import kotlin.Suppress 14 | import kotlin.Throwable 15 | import kotlin.Unit 16 | import kotlin.jvm.JvmName 17 | 18 | /** 19 | * cached extension 20 | */ 21 | @PublishedApi() 22 | internal val effect_singleton: SingleKEffect = object : arrow.fx.rx2.extensions.SingleKEffect {} 23 | 24 | @JvmName("runAsync") 25 | @Suppress( 26 | "UNCHECKED_CAST", 27 | "USELESS_CAST", 28 | "EXTENSION_SHADOWED_BY_MEMBER", 29 | "UNUSED_PARAMETER" 30 | ) 31 | @Deprecated(DeprecateRxJava) 32 | fun Kind.runAsync(arg1: Function1, Kind>): 33 | SingleK = arrow.fx.rx2.SingleK.effect().run { 34 | this@runAsync.runAsync(arg1) as arrow.fx.rx2.SingleK 35 | } 36 | 37 | @Suppress( 38 | "UNCHECKED_CAST", 39 | "NOTHING_TO_INLINE" 40 | ) 41 | @Deprecated(DeprecateRxJava) 42 | inline fun Companion.effect(): SingleKEffect = effect_singleton 43 | -------------------------------------------------------------------------------- /arrow-fx-reactor/src/main/kotlin/arrow/fx/reactor/extensions/fluxk/effect/FluxKEffect.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.reactor.extensions.fluxk.effect 2 | 3 | import arrow.Kind 4 | import arrow.core.Either 5 | import arrow.fx.reactor.DeprecateReactor 6 | import arrow.fx.reactor.FluxK 7 | import arrow.fx.reactor.FluxK.Companion 8 | import arrow.fx.reactor.ForFluxK 9 | import arrow.fx.reactor.extensions.FluxKEffect 10 | import kotlin.Deprecated 11 | import kotlin.Function1 12 | import kotlin.PublishedApi 13 | import kotlin.Suppress 14 | import kotlin.Throwable 15 | import kotlin.Unit 16 | import kotlin.jvm.JvmName 17 | 18 | /** 19 | * cached extension 20 | */ 21 | @PublishedApi() 22 | internal val effect_singleton: FluxKEffect = object : arrow.fx.reactor.extensions.FluxKEffect {} 23 | 24 | @JvmName("runAsync") 25 | @Suppress( 26 | "UNCHECKED_CAST", 27 | "USELESS_CAST", 28 | "EXTENSION_SHADOWED_BY_MEMBER", 29 | "UNUSED_PARAMETER" 30 | ) 31 | @Deprecated(DeprecateReactor) 32 | fun Kind.runAsync(arg1: Function1, Kind>): 33 | FluxK = arrow.fx.reactor.FluxK.effect().run { 34 | this@runAsync.runAsync(arg1) as arrow.fx.reactor.FluxK 35 | } 36 | 37 | @Suppress( 38 | "UNCHECKED_CAST", 39 | "NOTHING_TO_INLINE" 40 | ) 41 | @Deprecated(DeprecateReactor) 42 | inline fun Companion.effect(): FluxKEffect = effect_singleton 43 | -------------------------------------------------------------------------------- /arrow-fx-reactor/src/main/kotlin/arrow/fx/reactor/extensions/monok/effect/MonoKEffect.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.reactor.extensions.monok.effect 2 | 3 | import arrow.Kind 4 | import arrow.core.Either 5 | import arrow.fx.reactor.DeprecateReactor 6 | import arrow.fx.reactor.ForMonoK 7 | import arrow.fx.reactor.MonoK 8 | import arrow.fx.reactor.MonoK.Companion 9 | import arrow.fx.reactor.extensions.MonoKEffect 10 | import kotlin.Deprecated 11 | import kotlin.Function1 12 | import kotlin.PublishedApi 13 | import kotlin.Suppress 14 | import kotlin.Throwable 15 | import kotlin.Unit 16 | import kotlin.jvm.JvmName 17 | 18 | /** 19 | * cached extension 20 | */ 21 | @PublishedApi() 22 | internal val effect_singleton: MonoKEffect = object : arrow.fx.reactor.extensions.MonoKEffect {} 23 | 24 | @JvmName("runAsync") 25 | @Suppress( 26 | "UNCHECKED_CAST", 27 | "USELESS_CAST", 28 | "EXTENSION_SHADOWED_BY_MEMBER", 29 | "UNUSED_PARAMETER" 30 | ) 31 | @Deprecated(DeprecateReactor) 32 | fun Kind.runAsync(arg1: Function1, Kind>): 33 | MonoK = arrow.fx.reactor.MonoK.effect().run { 34 | this@runAsync.runAsync(arg1) as arrow.fx.reactor.MonoK 35 | } 36 | 37 | @Suppress( 38 | "UNCHECKED_CAST", 39 | "NOTHING_TO_INLINE" 40 | ) 41 | @Deprecated(DeprecateReactor) 42 | inline fun Companion.effect(): MonoKEffect = effect_singleton 43 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/extensions/io/semigroup/IOSemigroup.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.extensions.io.semigroup 2 | 3 | import arrow.fx.IO 4 | import arrow.fx.IO.Companion 5 | import arrow.fx.IODeprecation 6 | import arrow.fx.extensions.IOSemigroup 7 | import arrow.typeclasses.Semigroup 8 | import kotlin.Deprecated 9 | import kotlin.Suppress 10 | import kotlin.jvm.JvmName 11 | 12 | @JvmName("plus") 13 | @Suppress( 14 | "UNCHECKED_CAST", 15 | "USELESS_CAST", 16 | "EXTENSION_SHADOWED_BY_MEMBER", 17 | "UNUSED_PARAMETER" 18 | ) 19 | @Deprecated(IODeprecation) 20 | fun IO.plus(SG: Semigroup, arg1: IO): IO = arrow.fx.IO.semigroup(SG).run { 21 | this@plus.plus(arg1) as arrow.fx.IO 22 | } 23 | 24 | @JvmName("maybeCombine") 25 | @Suppress( 26 | "UNCHECKED_CAST", 27 | "USELESS_CAST", 28 | "EXTENSION_SHADOWED_BY_MEMBER", 29 | "UNUSED_PARAMETER" 30 | ) 31 | @Deprecated(IODeprecation) 32 | fun IO.maybeCombine(SG: Semigroup, arg1: IO): IO = 33 | arrow.fx.IO.semigroup(SG).run { 34 | this@maybeCombine.maybeCombine(arg1) as arrow.fx.IO 35 | } 36 | 37 | @Suppress( 38 | "UNCHECKED_CAST", 39 | "NOTHING_TO_INLINE" 40 | ) 41 | @Deprecated(IODeprecation) 42 | inline fun Companion.semigroup(SG: Semigroup): IOSemigroup = object : 43 | arrow.fx.extensions.IOSemigroup { override fun SG(): arrow.typeclasses.Semigroup = SG } 44 | -------------------------------------------------------------------------------- /arrow-fx-coroutines/src/main/kotlin/arrow/fx/coroutines/timer.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.coroutines 2 | 3 | import kotlinx.coroutines.delay 4 | import kotlinx.coroutines.withTimeoutOrNull 5 | 6 | /** 7 | * Sleeps for a given [duration] without blocking a thread. 8 | * 9 | * ```kotlin:ank:playground 10 | * import arrow.fx.coroutines.* 11 | * 12 | * suspend fun main(): Unit { 13 | * sleep(5.seconds) 14 | * println("Message after sleeping") 15 | * } 16 | * ``` 17 | **/ 18 | @Deprecated("Use delay", ReplaceWith("delay(duration.millis)", "kotlinx.coroutines.delay")) 19 | suspend fun sleep(duration: Duration): Unit = 20 | delay(duration.millis) 21 | 22 | /** 23 | * Returns the result of [fa] within the specified [duration] or returns null. 24 | * 25 | * ```kotlin:ank:playground 26 | * import arrow.fx.coroutines.* 27 | * 28 | * suspend fun main(): Unit { 29 | * timeOutOrNull(2.seconds) { 30 | * sleep(5.seconds) 31 | * "Message from lazy task" 32 | * }.also(::println) 33 | * 34 | * timeOutOrNull(2.seconds) { 35 | * "Message from fast task" 36 | * }.also(::println) 37 | * } 38 | * ``` 39 | **/ 40 | @Deprecated("use withTimeOutOrNull", ReplaceWith("withTimeoutOrNull(duration.millis)", "kotlinx.coroutines.withTimeoutOrNull")) 41 | suspend fun timeOutOrNull(duration: Duration, fa: suspend () -> A): A? = 42 | withTimeoutOrNull(duration.millis) { fa.invoke() } 43 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/src/jmh/kotlin/arrow/benchmarks/Async.kt: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks 2 | 3 | import arrow.fx.IO 4 | import arrow.fx.IODispatchers 5 | import org.openjdk.jmh.annotations.Benchmark 6 | import org.openjdk.jmh.annotations.CompilerControl 7 | import org.openjdk.jmh.annotations.Fork 8 | import org.openjdk.jmh.annotations.Measurement 9 | import org.openjdk.jmh.annotations.Param 10 | import org.openjdk.jmh.annotations.Scope 11 | import org.openjdk.jmh.annotations.State 12 | import org.openjdk.jmh.annotations.Warmup 13 | import java.util.concurrent.TimeUnit 14 | 15 | @State(Scope.Thread) 16 | @Fork(2) 17 | @Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS) 18 | @Measurement(iterations = 10) 19 | @CompilerControl(CompilerControl.Mode.DONT_INLINE) 20 | open class Async { 21 | 22 | @Param("3000") 23 | var size: Int = 0 24 | 25 | private fun ioAsyncLoop(i: Int): IO = 26 | IO.unit.continueOn(IODispatchers.CommonPool).followedBy( 27 | if (i > size) IO.just(i) else ioAsyncLoop(i + 1) 28 | ) 29 | 30 | @Benchmark 31 | fun io(): Int = 32 | ioAsyncLoop(0).unsafeRunSync() 33 | 34 | @Benchmark 35 | fun catsIO(): Int = 36 | arrow.benchmarks.effects.scala.cats.`Async$`.`MODULE$`.unsafeIOAsyncLoop(size, 0) 37 | 38 | @Benchmark 39 | fun scalazZIO(): Int = 40 | arrow.benchmarks.effects.scala.zio.`Async$`.`MODULE$`.unsafeIOAsyncLoop(size, 0) 41 | } 42 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/extensions/io/monoid/IOMonoid.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.extensions.io.monoid 2 | 3 | import arrow.fx.IO 4 | import arrow.fx.IO.Companion 5 | import arrow.fx.IODeprecation 6 | import arrow.fx.extensions.IOMonoid 7 | import arrow.typeclasses.Monoid 8 | import kotlin.Deprecated 9 | import kotlin.Suppress 10 | import kotlin.collections.Collection 11 | import kotlin.collections.List 12 | import kotlin.jvm.JvmName 13 | 14 | @JvmName("combineAll") 15 | @Suppress( 16 | "UNCHECKED_CAST", 17 | "USELESS_CAST", 18 | "EXTENSION_SHADOWED_BY_MEMBER", 19 | "UNUSED_PARAMETER" 20 | ) 21 | @Deprecated(IODeprecation) 22 | fun Collection>.combineAll(SG: Monoid): IO = arrow.fx.IO.monoid(SG).run { 23 | this@combineAll.combineAll() as arrow.fx.IO 24 | } 25 | 26 | @JvmName("combineAll") 27 | @Suppress( 28 | "UNCHECKED_CAST", 29 | "USELESS_CAST", 30 | "EXTENSION_SHADOWED_BY_MEMBER", 31 | "UNUSED_PARAMETER" 32 | ) 33 | @Deprecated(IODeprecation) 34 | fun combineAll(SG: Monoid, arg0: List>): IO = arrow.fx.IO 35 | .monoid(SG) 36 | .combineAll(arg0) as arrow.fx.IO 37 | 38 | @Suppress( 39 | "UNCHECKED_CAST", 40 | "NOTHING_TO_INLINE" 41 | ) 42 | @Deprecated(IODeprecation) 43 | inline fun Companion.monoid(SG: Monoid): IOMonoid = object : 44 | arrow.fx.extensions.IOMonoid { override fun SG(): arrow.typeclasses.Monoid = SG } 45 | -------------------------------------------------------------------------------- /arrow-fx-rx2/src/main/kotlin/arrow/fx/rx2/extensions/flowablek/effect/FlowableKEffect.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.rx2.extensions.flowablek.effect 2 | 3 | import arrow.Kind 4 | import arrow.core.Either 5 | import arrow.fx.rx2.DeprecateRxJava 6 | import arrow.fx.rx2.FlowableK 7 | import arrow.fx.rx2.FlowableK.Companion 8 | import arrow.fx.rx2.ForFlowableK 9 | import arrow.fx.rx2.extensions.FlowableKEffect 10 | import kotlin.Deprecated 11 | import kotlin.Function1 12 | import kotlin.PublishedApi 13 | import kotlin.Suppress 14 | import kotlin.Throwable 15 | import kotlin.Unit 16 | import kotlin.jvm.JvmName 17 | 18 | /** 19 | * cached extension 20 | */ 21 | @PublishedApi() 22 | internal val effect_singleton: FlowableKEffect = object : arrow.fx.rx2.extensions.FlowableKEffect {} 23 | 24 | @JvmName("runAsync") 25 | @Suppress( 26 | "UNCHECKED_CAST", 27 | "USELESS_CAST", 28 | "EXTENSION_SHADOWED_BY_MEMBER", 29 | "UNUSED_PARAMETER" 30 | ) 31 | @Deprecated(DeprecateRxJava) 32 | fun Kind.runAsync( 33 | arg1: Function1, Kind> 35 | ): FlowableK = arrow.fx.rx2.FlowableK.effect().run { 36 | this@runAsync.runAsync(arg1) as arrow.fx.rx2.FlowableK 37 | } 38 | 39 | @Suppress( 40 | "UNCHECKED_CAST", 41 | "NOTHING_TO_INLINE" 42 | ) 43 | @Deprecated(DeprecateRxJava) 44 | inline fun Companion.effect(): FlowableKEffect = effect_singleton 45 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/src/jmh/kotlin/arrow/benchmarks/RacePair.kt: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks 2 | 3 | import arrow.core.extensions.list.foldable.foldLeft 4 | import arrow.fx.IO 5 | import arrow.fx.IODispatchers 6 | import arrow.fx.extensions.io.monad.map 7 | import org.openjdk.jmh.annotations.Benchmark 8 | import org.openjdk.jmh.annotations.CompilerControl 9 | import org.openjdk.jmh.annotations.Fork 10 | import org.openjdk.jmh.annotations.Measurement 11 | import org.openjdk.jmh.annotations.Param 12 | import org.openjdk.jmh.annotations.Scope 13 | import org.openjdk.jmh.annotations.State 14 | import org.openjdk.jmh.annotations.Warmup 15 | import java.util.concurrent.TimeUnit 16 | 17 | @State(Scope.Thread) 18 | @Fork(2) 19 | @Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS) 20 | @Measurement(iterations = 10) 21 | @CompilerControl(CompilerControl.Mode.DONT_INLINE) 22 | open class RacePair { 23 | 24 | @Param("100") 25 | var size: Int = 0 26 | 27 | private fun racePairHelper(): IO = (0 until size).toList().foldLeft(IO { 0 }) { acc, _ -> 28 | IO.racePair(IODispatchers.CommonPool, acc, IO { 1 }).flatMap { ei -> 29 | ei.fold( 30 | { a, (_, cancel) -> 31 | cancel.map { a } 32 | }, 33 | { (_, cancel), b -> 34 | cancel.map { b } 35 | } 36 | ) 37 | } 38 | } 39 | 40 | @Benchmark 41 | fun io(): Int = racePairHelper().unsafeRunSync() 42 | } 43 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/src/jmh/kotlin/arrow/benchmarks/Pure.kt: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks 2 | 3 | import arrow.fx.IO 4 | import org.openjdk.jmh.annotations.Benchmark 5 | import org.openjdk.jmh.annotations.CompilerControl 6 | import org.openjdk.jmh.annotations.Fork 7 | import org.openjdk.jmh.annotations.Measurement 8 | import org.openjdk.jmh.annotations.Param 9 | import org.openjdk.jmh.annotations.Scope 10 | import org.openjdk.jmh.annotations.State 11 | import org.openjdk.jmh.annotations.Warmup 12 | import java.util.concurrent.TimeUnit 13 | 14 | @State(Scope.Thread) 15 | @Fork(2) 16 | @Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS) 17 | @Measurement(iterations = 10) 18 | @CompilerControl(CompilerControl.Mode.DONT_INLINE) 19 | open class Pure { 20 | 21 | @Param("3000") 22 | var size: Int = 0 23 | 24 | private fun ioPureLoop(i: Int): IO = 25 | IO.just(i).flatMap { j -> 26 | if (j > size) IO.just(j) else ioPureLoop(j + 1) 27 | } 28 | 29 | @Benchmark 30 | fun io(): Int = 31 | ioPureLoop(0).unsafeRunSync() 32 | 33 | @Benchmark 34 | fun catsIO(): Int = 35 | arrow.benchmarks.effects.scala.cats.`Pure$`.`MODULE$`.unsafeIOPureLoop(size, 0) 36 | 37 | @Benchmark 38 | fun scalazZio(): Int = 39 | arrow.benchmarks.effects.scala.zio.`Pure$`.`MODULE$`.unsafeIOPureLoop(size, 0) 40 | 41 | @Benchmark 42 | fun kio(): Int = 43 | arrow.benchmarks.effects.kio.Pure.unsafeKIOPureLoop(size, 0) 44 | } 45 | -------------------------------------------------------------------------------- /arrow-docs/src/main/kotlin/OpticsHelper.kt: -------------------------------------------------------------------------------- 1 | package arrow.optics 2 | 3 | import arrow.core.Either 4 | import arrow.core.Option 5 | 6 | @optics 7 | data class Pos(val x: Int, val y: Int) { 8 | companion object 9 | } 10 | 11 | @optics 12 | data class Account(val balance: Int, val available: Int) { 13 | companion object 14 | } 15 | 16 | @optics 17 | data class Person(val age: Int?, val address: Option
) { 18 | companion object 19 | } 20 | 21 | @optics 22 | data class Street(val number: Int, val name: String) { 23 | companion object 24 | } 25 | 26 | @optics 27 | data class Address(val city: String, val street: Street) { 28 | companion object 29 | } 30 | 31 | @optics 32 | data class Company(val name: String, val address: Address) { 33 | companion object 34 | } 35 | 36 | @optics 37 | data class Employee(val name: String, val company: Company) { 38 | companion object 39 | } 40 | 41 | @optics 42 | sealed class Shape { 43 | companion object 44 | 45 | @optics 46 | data class Circle(val radius: Double) : Shape() { 47 | companion object 48 | } 49 | 50 | @optics 51 | data class Rectangle(val width: Double, val height: Double) : Shape() { 52 | companion object 53 | } 54 | } 55 | 56 | @optics data class HealthPack(val amountLeft: Int) { 57 | companion object 58 | } 59 | 60 | object OutOfPacks 61 | 62 | @optics data class Inventory(val item: Either) { 63 | companion object 64 | } 65 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/src/jmh/kotlin/arrow/benchmarks/Delay.kt: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks 2 | 3 | import arrow.fx.IO 4 | import org.openjdk.jmh.annotations.Benchmark 5 | import org.openjdk.jmh.annotations.CompilerControl 6 | import org.openjdk.jmh.annotations.Fork 7 | import org.openjdk.jmh.annotations.Measurement 8 | import org.openjdk.jmh.annotations.Param 9 | import org.openjdk.jmh.annotations.Scope 10 | import org.openjdk.jmh.annotations.State 11 | import org.openjdk.jmh.annotations.Warmup 12 | import java.util.concurrent.TimeUnit 13 | 14 | @State(Scope.Thread) 15 | @Fork(2) 16 | @Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS) 17 | @Measurement(iterations = 10) 18 | @CompilerControl(CompilerControl.Mode.DONT_INLINE) 19 | open class Delay { 20 | 21 | @Param("3000") 22 | var size: Int = 0 23 | 24 | private fun ioDelayLoop(i: Int): IO = 25 | IO { i }.flatMap { j -> 26 | if (j > size) IO { j } else ioDelayLoop(j + 1) 27 | } 28 | 29 | @Benchmark 30 | fun io(): Int = 31 | ioDelayLoop(0).unsafeRunSync() 32 | 33 | @Benchmark 34 | fun catsIO(): Int = 35 | arrow.benchmarks.effects.scala.cats.`Delay$`.`MODULE$`.unsafeIODelayLoop(size, 0) 36 | 37 | @Benchmark 38 | fun scalaZIO(): Int = 39 | arrow.benchmarks.effects.scala.zio.`Delay$`.`MODULE$`.unsafeIODelayLoop(size, 0) 40 | 41 | @Benchmark 42 | fun kio(): Int = 43 | arrow.benchmarks.effects.kio.Delay.unsafeIODelayLoop(size, 0) 44 | } 45 | -------------------------------------------------------------------------------- /arrow-fx-rx2/src/main/kotlin/arrow/fx/rx2/extensions/observablek/effect/ObservableKEffect.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.rx2.extensions.observablek.effect 2 | 3 | import arrow.Kind 4 | import arrow.core.Either 5 | import arrow.fx.rx2.DeprecateRxJava 6 | import arrow.fx.rx2.ForObservableK 7 | import arrow.fx.rx2.ObservableK 8 | import arrow.fx.rx2.ObservableK.Companion 9 | import arrow.fx.rx2.extensions.ObservableKEffect 10 | import kotlin.Deprecated 11 | import kotlin.Function1 12 | import kotlin.PublishedApi 13 | import kotlin.Suppress 14 | import kotlin.Throwable 15 | import kotlin.Unit 16 | import kotlin.jvm.JvmName 17 | 18 | /** 19 | * cached extension 20 | */ 21 | @PublishedApi() 22 | internal val effect_singleton: ObservableKEffect = object : 23 | arrow.fx.rx2.extensions.ObservableKEffect {} 24 | 25 | @JvmName("runAsync") 26 | @Suppress( 27 | "UNCHECKED_CAST", 28 | "USELESS_CAST", 29 | "EXTENSION_SHADOWED_BY_MEMBER", 30 | "UNUSED_PARAMETER" 31 | ) 32 | @Deprecated(DeprecateRxJava) 33 | fun Kind.runAsync( 34 | arg1: Function1, Kind> 36 | ): ObservableK = arrow.fx.rx2.ObservableK.effect().run { 37 | this@runAsync.runAsync(arg1) as arrow.fx.rx2.ObservableK 38 | } 39 | 40 | @Suppress( 41 | "UNCHECKED_CAST", 42 | "NOTHING_TO_INLINE" 43 | ) 44 | @Deprecated(DeprecateRxJava) 45 | inline fun Companion.effect(): ObservableKEffect = effect_singleton 46 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/src/jmh/kotlin/arrow/benchmarks/DeepBind.kt: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks 2 | 3 | import arrow.fx.IO 4 | import org.openjdk.jmh.annotations.Benchmark 5 | import org.openjdk.jmh.annotations.CompilerControl 6 | import org.openjdk.jmh.annotations.Fork 7 | import org.openjdk.jmh.annotations.Measurement 8 | import org.openjdk.jmh.annotations.Param 9 | import org.openjdk.jmh.annotations.Scope 10 | import org.openjdk.jmh.annotations.State 11 | import org.openjdk.jmh.annotations.Warmup 12 | import java.util.concurrent.TimeUnit 13 | 14 | @State(Scope.Thread) 15 | @Fork(2) 16 | @Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS) 17 | @Measurement(iterations = 10) 18 | @CompilerControl(CompilerControl.Mode.DONT_INLINE) 19 | open class DeepBind { 20 | 21 | @Param("20") 22 | var depth: Int = 0 23 | 24 | fun ioFibLazy(n: Int): IO = 25 | if (n <= 1) IO { n } 26 | else ioFibLazy(n - 1).flatMap { a -> 27 | ioFibLazy(n - 2).flatMap { b -> IO { a + b } } 28 | } 29 | 30 | @Benchmark 31 | fun io(): Int = 32 | ioFibLazy(depth).unsafeRunSync() 33 | 34 | @Benchmark 35 | fun cats(): Any = 36 | arrow.benchmarks.effects.scala.cats.`DeepBind$`.`MODULE$`.fib(depth).unsafeRunSync() 37 | 38 | @Benchmark 39 | fun zio(): Any = 40 | arrow.benchmarks.effects.scala.zio.`DeepBind$`.`MODULE$`.fib(depth) 41 | 42 | @Benchmark 43 | fun kio(): Any = 44 | arrow.benchmarks.effects.kio.DeepBind.fib(depth) 45 | } 46 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/internal/ConcurrentParMap2.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.internal 2 | 3 | import arrow.Kind 4 | import arrow.fx.typeclasses.Concurrent 5 | import kotlin.coroutines.CoroutineContext 6 | 7 | internal fun Concurrent.parMap2( 8 | ctx: CoroutineContext, 9 | fa: Kind, 10 | fb: Kind, 11 | f: (A, B) -> C 12 | ): Kind = ctx.run { 13 | tupledN(fb.fork(this), fa.fork(this)).bracket( 14 | use = { (fiberB, fiberA) -> 15 | racePair(fiberA.join().attempt(), fiberB.join().attempt()).flatMap { pairResult -> 16 | pairResult.fold( 17 | { attemptedA, fiberB -> 18 | attemptedA.fold( 19 | { error -> 20 | raiseError(error) 21 | }, 22 | { a -> 23 | fiberB.join().rethrow().map { b -> 24 | f(a, b) 25 | } 26 | } 27 | ) 28 | }, 29 | { fiberA, attemptedB -> 30 | attemptedB.fold( 31 | { error -> 32 | raiseError(error) 33 | }, 34 | { b -> 35 | fiberA.join().rethrow().map { a -> 36 | f(a, b) 37 | } 38 | } 39 | ) 40 | } 41 | ) 42 | } 43 | }, 44 | release = { (fiberA, fiberB) -> 45 | fiberA.cancel().followedBy(fiberB.cancel()) 46 | } 47 | ) 48 | } 49 | -------------------------------------------------------------------------------- /arrow-fx-rx2/src/main/kotlin/arrow/fx/rx2/extensions/maybek/dispatchers/MaybeKDispatchers.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.rx2.extensions.maybek.dispatchers 2 | 3 | import arrow.fx.rx2.DeprecateRxJava 4 | import arrow.fx.rx2.MaybeK.Companion 5 | import arrow.fx.rx2.extensions.MaybeKDispatchers 6 | import kotlin.Deprecated 7 | import kotlin.PublishedApi 8 | import kotlin.Suppress 9 | import kotlin.coroutines.CoroutineContext 10 | import kotlin.jvm.JvmName 11 | 12 | /** 13 | * cached extension 14 | */ 15 | @PublishedApi() 16 | internal val dispatchers_singleton: MaybeKDispatchers = object : 17 | arrow.fx.rx2.extensions.MaybeKDispatchers {} 18 | 19 | @JvmName("default") 20 | @Suppress( 21 | "UNCHECKED_CAST", 22 | "USELESS_CAST", 23 | "EXTENSION_SHADOWED_BY_MEMBER", 24 | "UNUSED_PARAMETER" 25 | ) 26 | @Deprecated(DeprecateRxJava) 27 | fun default(): CoroutineContext = arrow.fx.rx2.MaybeK 28 | .dispatchers() 29 | .default() as kotlin.coroutines.CoroutineContext 30 | 31 | @JvmName("io") 32 | @Suppress( 33 | "UNCHECKED_CAST", 34 | "USELESS_CAST", 35 | "EXTENSION_SHADOWED_BY_MEMBER", 36 | "UNUSED_PARAMETER" 37 | ) 38 | @Deprecated(DeprecateRxJava) 39 | fun io(): CoroutineContext = arrow.fx.rx2.MaybeK 40 | .dispatchers() 41 | .io() as kotlin.coroutines.CoroutineContext 42 | 43 | @Suppress( 44 | "UNCHECKED_CAST", 45 | "NOTHING_TO_INLINE" 46 | ) 47 | @Deprecated(DeprecateRxJava) 48 | inline fun Companion.dispatchers(): MaybeKDispatchers = dispatchers_singleton 49 | -------------------------------------------------------------------------------- /arrow-fx-rx2/src/main/kotlin/arrow/fx/rx2/extensions/singlek/dispatchers/SingleKDispatchers.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.rx2.extensions.singlek.dispatchers 2 | 3 | import arrow.fx.rx2.DeprecateRxJava 4 | import arrow.fx.rx2.SingleK.Companion 5 | import arrow.fx.rx2.extensions.SingleKDispatchers 6 | import kotlin.Deprecated 7 | import kotlin.PublishedApi 8 | import kotlin.Suppress 9 | import kotlin.coroutines.CoroutineContext 10 | import kotlin.jvm.JvmName 11 | 12 | /** 13 | * cached extension 14 | */ 15 | @PublishedApi() 16 | internal val dispatchers_singleton: SingleKDispatchers = object : 17 | arrow.fx.rx2.extensions.SingleKDispatchers {} 18 | 19 | @JvmName("default") 20 | @Suppress( 21 | "UNCHECKED_CAST", 22 | "USELESS_CAST", 23 | "EXTENSION_SHADOWED_BY_MEMBER", 24 | "UNUSED_PARAMETER" 25 | ) 26 | @Deprecated(DeprecateRxJava) 27 | fun default(): CoroutineContext = arrow.fx.rx2.SingleK 28 | .dispatchers() 29 | .default() as kotlin.coroutines.CoroutineContext 30 | 31 | @JvmName("io") 32 | @Suppress( 33 | "UNCHECKED_CAST", 34 | "USELESS_CAST", 35 | "EXTENSION_SHADOWED_BY_MEMBER", 36 | "UNUSED_PARAMETER" 37 | ) 38 | @Deprecated(DeprecateRxJava) 39 | fun io(): CoroutineContext = arrow.fx.rx2.SingleK 40 | .dispatchers() 41 | .io() as kotlin.coroutines.CoroutineContext 42 | 43 | @Suppress( 44 | "UNCHECKED_CAST", 45 | "NOTHING_TO_INLINE" 46 | ) 47 | @Deprecated(DeprecateRxJava) 48 | inline fun Companion.dispatchers(): SingleKDispatchers = dispatchers_singleton 49 | -------------------------------------------------------------------------------- /arrow-fx-coroutines/src/test/kotlin/arrow/fx/coroutines/PromiseTest.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.coroutines 2 | 3 | import arrow.core.Either 4 | import io.kotest.matchers.shouldBe 5 | 6 | class PromiseTest : ArrowFxSpec( 7 | spec = { 8 | 9 | class MyException : Exception() 10 | 11 | val exception = MyException() 12 | 13 | "complete" { 14 | val p = Promise() 15 | p.complete(1) shouldBe Either.Right(Unit) 16 | p.get() shouldBe 1 17 | } 18 | 19 | "complete twice should result in Promise.AlreadyFulfilled" { 20 | val p = Promise() 21 | p.complete(1) shouldBe Either.Right(Unit) 22 | p.complete(2) shouldBe Either.Left(Promise.AlreadyFulfilled) 23 | p.get() shouldBe 1 24 | } 25 | 26 | "get blocks until set" { 27 | val r = Atomic(0) 28 | val modifyGate = Promise() 29 | val readGate = Promise() 30 | 31 | ForkAndForget { 32 | modifyGate.get() 33 | r.update { i -> i * 2 } 34 | readGate.complete(0) 35 | } 36 | 37 | ForkAndForget { 38 | r.set(1) 39 | modifyGate.complete(0) 40 | } 41 | 42 | readGate.get() 43 | r.get() shouldBe 2 44 | } 45 | 46 | "tryGet returns None for empty Promise" { 47 | Promise().tryGet() shouldBe null 48 | } 49 | 50 | "tryGet returns Some for completed promise" { 51 | val p = Promise() 52 | p.complete(1) 53 | p.tryGet() shouldBe 1 54 | } 55 | } 56 | ) 57 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/extensions/io/concurrentEffect/IODefaultConcurrentEffect.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.extensions.io.concurrentEffect 2 | 3 | import arrow.Kind 4 | import arrow.core.Either 5 | import arrow.fx.ForIO 6 | import arrow.fx.IO 7 | import arrow.fx.IO.Companion 8 | import arrow.fx.IODeprecation 9 | import arrow.fx.extensions.IODefaultConcurrentEffect 10 | import kotlin.Deprecated 11 | import kotlin.Function0 12 | import kotlin.Function1 13 | import kotlin.PublishedApi 14 | import kotlin.Suppress 15 | import kotlin.Throwable 16 | import kotlin.Unit 17 | import kotlin.jvm.JvmName 18 | 19 | /** 20 | * cached extension 21 | */ 22 | @PublishedApi() 23 | internal val concurrentEffect_singleton: IODefaultConcurrentEffect = object : 24 | arrow.fx.extensions.IODefaultConcurrentEffect {} 25 | 26 | @JvmName("runAsyncCancellable") 27 | @Suppress( 28 | "UNCHECKED_CAST", 29 | "USELESS_CAST", 30 | "EXTENSION_SHADOWED_BY_MEMBER", 31 | "UNUSED_PARAMETER" 32 | ) 33 | @Deprecated(IODeprecation) 34 | fun Kind.runAsyncCancellable(cb: Function1, Kind>): 35 | IO> = arrow.fx.IO.concurrentEffect().run { 36 | this@runAsyncCancellable.runAsyncCancellable(cb) as arrow.fx.IO> 37 | } 38 | 39 | @Suppress( 40 | "UNCHECKED_CAST", 41 | "NOTHING_TO_INLINE" 42 | ) 43 | @Deprecated(IODeprecation) 44 | inline fun Companion.concurrentEffect(): IODefaultConcurrentEffect = concurrentEffect_singleton 45 | -------------------------------------------------------------------------------- /arrow-fx-rx2/src/main/kotlin/arrow/fx/rx2/extensions/flowablek/dispatchers/FlowableKDispatchers.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.rx2.extensions.flowablek.dispatchers 2 | 3 | import arrow.fx.rx2.DeprecateRxJava 4 | import arrow.fx.rx2.FlowableK.Companion 5 | import arrow.fx.rx2.extensions.FlowableKDispatchers 6 | import kotlin.Deprecated 7 | import kotlin.PublishedApi 8 | import kotlin.Suppress 9 | import kotlin.coroutines.CoroutineContext 10 | import kotlin.jvm.JvmName 11 | 12 | /** 13 | * cached extension 14 | */ 15 | @PublishedApi() 16 | internal val dispatchers_singleton: FlowableKDispatchers = object : 17 | arrow.fx.rx2.extensions.FlowableKDispatchers {} 18 | 19 | @JvmName("default") 20 | @Suppress( 21 | "UNCHECKED_CAST", 22 | "USELESS_CAST", 23 | "EXTENSION_SHADOWED_BY_MEMBER", 24 | "UNUSED_PARAMETER" 25 | ) 26 | @Deprecated(DeprecateRxJava) 27 | fun default(): CoroutineContext = arrow.fx.rx2.FlowableK 28 | .dispatchers() 29 | .default() as kotlin.coroutines.CoroutineContext 30 | 31 | @JvmName("io") 32 | @Suppress( 33 | "UNCHECKED_CAST", 34 | "USELESS_CAST", 35 | "EXTENSION_SHADOWED_BY_MEMBER", 36 | "UNUSED_PARAMETER" 37 | ) 38 | @Deprecated(DeprecateRxJava) 39 | fun io(): CoroutineContext = arrow.fx.rx2.FlowableK 40 | .dispatchers() 41 | .io() as kotlin.coroutines.CoroutineContext 42 | 43 | @Suppress( 44 | "UNCHECKED_CAST", 45 | "NOTHING_TO_INLINE" 46 | ) 47 | @Deprecated(DeprecateRxJava) 48 | inline fun Companion.dispatchers(): FlowableKDispatchers = dispatchers_singleton 49 | -------------------------------------------------------------------------------- /arrow-fx-rx2/src/main/kotlin/arrow/fx/rx2/extensions/observablek/dispatchers/ObservableKDispatchers.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.rx2.extensions.observablek.dispatchers 2 | 3 | import arrow.fx.rx2.DeprecateRxJava 4 | import arrow.fx.rx2.ObservableK.Companion 5 | import arrow.fx.rx2.extensions.ObservableKDispatchers 6 | import kotlin.Deprecated 7 | import kotlin.PublishedApi 8 | import kotlin.Suppress 9 | import kotlin.coroutines.CoroutineContext 10 | import kotlin.jvm.JvmName 11 | 12 | /** 13 | * cached extension 14 | */ 15 | @PublishedApi() 16 | internal val dispatchers_singleton: ObservableKDispatchers = object : 17 | arrow.fx.rx2.extensions.ObservableKDispatchers {} 18 | 19 | @JvmName("default") 20 | @Suppress( 21 | "UNCHECKED_CAST", 22 | "USELESS_CAST", 23 | "EXTENSION_SHADOWED_BY_MEMBER", 24 | "UNUSED_PARAMETER" 25 | ) 26 | @Deprecated(DeprecateRxJava) 27 | fun default(): CoroutineContext = arrow.fx.rx2.ObservableK 28 | .dispatchers() 29 | .default() as kotlin.coroutines.CoroutineContext 30 | 31 | @JvmName("io") 32 | @Suppress( 33 | "UNCHECKED_CAST", 34 | "USELESS_CAST", 35 | "EXTENSION_SHADOWED_BY_MEMBER", 36 | "UNUSED_PARAMETER" 37 | ) 38 | @Deprecated(DeprecateRxJava) 39 | fun io(): CoroutineContext = arrow.fx.rx2.ObservableK 40 | .dispatchers() 41 | .io() as kotlin.coroutines.CoroutineContext 42 | 43 | @Suppress( 44 | "UNCHECKED_CAST", 45 | "NOTHING_TO_INLINE" 46 | ) 47 | @Deprecated(DeprecateRxJava) 48 | inline fun Companion.dispatchers(): ObservableKDispatchers = dispatchers_singleton 49 | -------------------------------------------------------------------------------- /arrow-fx-coroutines/src/main/kotlin/arrow/fx/coroutines/cancelBoundary.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.coroutines 2 | 3 | import kotlinx.coroutines.ensureActive 4 | import kotlin.coroutines.coroutineContext 5 | 6 | /** 7 | * Inserts a cancellable boundary. 8 | * 9 | * In a cancellable environment, we need to add mechanisms to react when cancellation is triggered. 10 | * In a coroutine, a cancel boundary checks for the cancellation status; it does not allow the coroutine to keep executing in the case cancellation was triggered. 11 | * It is useful, for example, to cancel the continuation of a loop, as shown in this code snippet: 12 | * 13 | * ```kotlin:ank:playground 14 | * import arrow.fx.coroutines.* 15 | * 16 | * //sampleStart 17 | * suspend fun forever(): Unit { 18 | * while(true) { 19 | * println("I am getting dizzy...") 20 | * cancelBoundary() // cancellable computation loop 21 | * } 22 | * } 23 | * 24 | * suspend fun main(): Unit { 25 | * val fiber = ForkConnected { 26 | * guaranteeCase({ forever() }) { exitCase -> 27 | * println("forever finished with $exitCase") 28 | * } 29 | * } 30 | * sleep(10.milliseconds) 31 | * fiber.cancel() 32 | * } 33 | * ``` 34 | */ 35 | @Deprecated( 36 | "Use coroutineContext.ensureActive()", 37 | ReplaceWith( 38 | "coroutineContext.ensureActive()", 39 | "kotlinx.coroutines.ensureActive", 40 | "kotlin.coroutines.coroutineContext" 41 | ) 42 | ) 43 | suspend fun cancelBoundary(): Unit = 44 | coroutineContext.ensureActive() 45 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/extensions/io/semigroupK/IOSemigroupK.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.extensions.io.semigroupK 2 | 3 | import arrow.Kind 4 | import arrow.fx.ForIO 5 | import arrow.fx.IO 6 | import arrow.fx.IO.Companion 7 | import arrow.fx.IODeprecation 8 | import arrow.fx.extensions.IOSemigroupK 9 | import arrow.typeclasses.Semigroup 10 | import kotlin.Deprecated 11 | import kotlin.PublishedApi 12 | import kotlin.Suppress 13 | import kotlin.jvm.JvmName 14 | 15 | /** 16 | * cached extension 17 | */ 18 | @PublishedApi() 19 | internal val semigroupK_singleton: IOSemigroupK = object : arrow.fx.extensions.IOSemigroupK {} 20 | 21 | @JvmName("combineK") 22 | @Suppress( 23 | "UNCHECKED_CAST", 24 | "USELESS_CAST", 25 | "EXTENSION_SHADOWED_BY_MEMBER", 26 | "UNUSED_PARAMETER" 27 | ) 28 | @Deprecated(IODeprecation) 29 | fun Kind.combineK(arg1: Kind): IO = arrow.fx.IO.semigroupK().run { 30 | this@combineK.combineK(arg1) as arrow.fx.IO 31 | } 32 | 33 | @JvmName("algebra") 34 | @Suppress( 35 | "UNCHECKED_CAST", 36 | "USELESS_CAST", 37 | "EXTENSION_SHADOWED_BY_MEMBER", 38 | "UNUSED_PARAMETER" 39 | ) 40 | @Deprecated(IODeprecation) 41 | fun algebra(): Semigroup> = arrow.fx.IO 42 | .semigroupK() 43 | .algebra() as arrow.typeclasses.Semigroup> 44 | 45 | @Suppress( 46 | "UNCHECKED_CAST", 47 | "NOTHING_TO_INLINE" 48 | ) 49 | @Deprecated(IODeprecation) 50 | inline fun Companion.semigroupK(): IOSemigroupK = semigroupK_singleton 51 | -------------------------------------------------------------------------------- /arrow-fx-coroutines-test/src/test/kotlin/arrow/fx/coroutines/PredefTest.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.coroutines 2 | 3 | import io.kotest.matchers.shouldBe 4 | import io.kotest.property.Arb 5 | import io.kotest.property.arbitrary.int 6 | import io.kotest.property.arbitrary.string 7 | import kotlin.coroutines.Continuation 8 | import kotlin.coroutines.EmptyCoroutineContext 9 | import kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED 10 | import kotlin.coroutines.intrinsics.startCoroutineUninterceptedOrReturn 11 | 12 | class PredefTest : ArrowFxSpec( 13 | spec = { 14 | 15 | "suspended always suspends" { 16 | checkAll(Arb.int()) { i -> 17 | val promise = UnsafePromise() 18 | 19 | val x = i.suspended() 20 | .startCoroutineUninterceptedOrReturn( 21 | Continuation(EmptyCoroutineContext) { 22 | promise.complete(it) 23 | } 24 | ) 25 | 26 | x shouldBe COROUTINE_SUSPENDED 27 | promise.join() shouldBe i 28 | } 29 | } 30 | 31 | "shift" { 32 | checkAll(Arb.string(), Arb.string()) { a, b -> 33 | val t0 = threadName.invoke() 34 | 35 | Resource.singleThreadContext(a) 36 | .zip(Resource.singleThreadContext(b)) 37 | .use { (ui, io) -> 38 | t0 shouldBe threadName.invoke() 39 | 40 | ui.shift() 41 | threadName.invoke() shouldBe a 42 | 43 | io.shift() 44 | threadName.invoke() shouldBe b 45 | } 46 | } 47 | } 48 | } 49 | ) 50 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/src/jmh/kotlin/arrow/benchmarks/AttemptNonRaised.kt: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks 2 | 3 | import arrow.fx.IO 4 | import org.openjdk.jmh.annotations.Benchmark 5 | import org.openjdk.jmh.annotations.CompilerControl 6 | import org.openjdk.jmh.annotations.Fork 7 | import org.openjdk.jmh.annotations.Measurement 8 | import org.openjdk.jmh.annotations.Param 9 | import org.openjdk.jmh.annotations.Scope 10 | import org.openjdk.jmh.annotations.State 11 | import org.openjdk.jmh.annotations.Warmup 12 | import java.util.concurrent.TimeUnit 13 | 14 | @State(Scope.Thread) 15 | @Fork(2) 16 | @Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS) 17 | @Measurement(iterations = 10) 18 | @CompilerControl(CompilerControl.Mode.DONT_INLINE) 19 | open class AttemptNonRaised { 20 | 21 | @Param("10000") 22 | var size: Int = 0 23 | 24 | private fun ioLoopHappy(size: Int, i: Int): IO = 25 | if (i < size) { 26 | IO { i + 1 }.attempt().flatMap { 27 | it.fold(IO.Companion::raiseError) { n -> ioLoopHappy(size, n) } 28 | } 29 | } else IO.just(1) 30 | 31 | @Benchmark 32 | fun io(): Int = 33 | ioLoopHappy(size, 0).unsafeRunSync() 34 | 35 | @Benchmark 36 | fun cats(): Any = 37 | arrow.benchmarks.effects.scala.cats.AttemptNonRaised.ioLoopHappy(size, 0).unsafeRunSync() 38 | 39 | @Benchmark 40 | fun zio(): Any = 41 | arrow.benchmarks.effects.scala.zio.AttemptNonRaised.run(size) 42 | 43 | @Benchmark 44 | fun kio(): Int = 45 | arrow.benchmarks.effects.kio.AttemptNonRaised.attemptNonRaised(size) 46 | } 47 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/extensions/duration/monoid/DurationMonoid.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.extensions.duration.monoid 2 | 3 | import arrow.fx.IODeprecation 4 | import arrow.fx.extensions.DurationMonoid 5 | import arrow.fx.typeclasses.Duration 6 | import arrow.fx.typeclasses.Duration.Companion 7 | import kotlin.Deprecated 8 | import kotlin.PublishedApi 9 | import kotlin.Suppress 10 | import kotlin.collections.Collection 11 | import kotlin.collections.List 12 | import kotlin.jvm.JvmName 13 | 14 | /** 15 | * cached extension 16 | */ 17 | @PublishedApi() 18 | internal val monoid_singleton: DurationMonoid = object : arrow.fx.extensions.DurationMonoid {} 19 | 20 | @JvmName("combineAll") 21 | @Suppress( 22 | "UNCHECKED_CAST", 23 | "USELESS_CAST", 24 | "EXTENSION_SHADOWED_BY_MEMBER", 25 | "UNUSED_PARAMETER" 26 | ) 27 | @Deprecated(IODeprecation) 28 | fun Collection.combineAll(): Duration = arrow.fx.typeclasses.Duration.monoid().run { 29 | this@combineAll.combineAll() as arrow.fx.typeclasses.Duration 30 | } 31 | 32 | @JvmName("combineAll") 33 | @Suppress( 34 | "UNCHECKED_CAST", 35 | "USELESS_CAST", 36 | "EXTENSION_SHADOWED_BY_MEMBER", 37 | "UNUSED_PARAMETER" 38 | ) 39 | @Deprecated(IODeprecation) 40 | fun combineAll(arg0: List): Duration = arrow.fx.typeclasses.Duration 41 | .monoid() 42 | .combineAll(arg0) as arrow.fx.typeclasses.Duration 43 | 44 | @Suppress( 45 | "UNCHECKED_CAST", 46 | "NOTHING_TO_INLINE" 47 | ) 48 | @Deprecated(IODeprecation) 49 | inline fun Companion.monoid(): DurationMonoid = monoid_singleton 50 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/extensions/duration/semigroup/DurationSemigroup.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.extensions.duration.semigroup 2 | 3 | import arrow.fx.IODeprecation 4 | import arrow.fx.extensions.DurationSemigroup 5 | import arrow.fx.typeclasses.Duration 6 | import arrow.fx.typeclasses.Duration.Companion 7 | import kotlin.Deprecated 8 | import kotlin.PublishedApi 9 | import kotlin.Suppress 10 | import kotlin.jvm.JvmName 11 | 12 | /** 13 | * cached extension 14 | */ 15 | @PublishedApi() 16 | internal val semigroup_singleton: DurationSemigroup = object : arrow.fx.extensions.DurationSemigroup 17 | {} 18 | 19 | @JvmName("plus") 20 | @Suppress( 21 | "UNCHECKED_CAST", 22 | "USELESS_CAST", 23 | "EXTENSION_SHADOWED_BY_MEMBER", 24 | "UNUSED_PARAMETER" 25 | ) 26 | @Deprecated(IODeprecation) 27 | operator fun Duration.plus(arg1: Duration): Duration = 28 | arrow.fx.typeclasses.Duration.semigroup().run { 29 | this@plus.plus(arg1) as arrow.fx.typeclasses.Duration 30 | } 31 | 32 | @JvmName("maybeCombine") 33 | @Suppress( 34 | "UNCHECKED_CAST", 35 | "USELESS_CAST", 36 | "EXTENSION_SHADOWED_BY_MEMBER", 37 | "UNUSED_PARAMETER" 38 | ) 39 | @Deprecated(IODeprecation) 40 | fun Duration.maybeCombine(arg1: Duration): Duration = 41 | arrow.fx.typeclasses.Duration.semigroup().run { 42 | this@maybeCombine.maybeCombine(arg1) as arrow.fx.typeclasses.Duration 43 | } 44 | 45 | @Suppress( 46 | "UNCHECKED_CAST", 47 | "NOTHING_TO_INLINE" 48 | ) 49 | @Deprecated(IODeprecation) 50 | inline fun Companion.semigroup(): DurationSemigroup = semigroup_singleton 51 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/Timer.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx 2 | 3 | import arrow.Kind 4 | import arrow.fx.internal.ConcurrentSleep 5 | import arrow.fx.typeclasses.Concurrent 6 | import arrow.fx.typeclasses.Duration 7 | 8 | /** 9 | * [Timer] allows to [sleep] for a [Duration] in [F]. 10 | * This behaviour can be derived from [Concurrent], and can be used to implement backing off retries etc. 11 | * 12 | * Since sleeping is done by [Timer] it allows for easy modification in testing by providing a no-op [TestTimer] 13 | */ 14 | @Deprecated(IODeprecation) 15 | interface Timer { 16 | /** 17 | * Sleeps for a given [duration] without blocking a thread. 18 | * 19 | * ```kotlin:ank:playground 20 | * import arrow.* 21 | * import arrow.fx.* 22 | * import arrow.fx.typeclasses.* 23 | * import arrow.fx.extensions.io.concurrent.concurrent 24 | * 25 | * fun main(args: Array) { 26 | * //sampleStart 27 | * fun Concurrent.delayHelloWorld(): Kind = 28 | * Timer(this).sleep(3.seconds).flatMap { 29 | * effect { println("Hello World!") } 30 | * } 31 | * //sampleEnd 32 | * IO.concurrent().delayHelloWorld() 33 | * .fix().unsafeRunSync() 34 | * } 35 | * ``` 36 | **/ 37 | fun sleep(duration: Duration): Kind 38 | 39 | @Deprecated(IODeprecation) 40 | companion object { 41 | operator fun invoke(CF: Concurrent): Timer = object : Timer { 42 | override fun sleep(duration: Duration): Kind = CF.ConcurrentSleep(duration) 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /arrow-fx-stm/src/test/kotlin/arrow/fx/stm/TArrayTest.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.stm 2 | 3 | import arrow.fx.coroutines.ArrowFxSpec 4 | import io.kotest.matchers.ints.shouldBeExactly 5 | import io.kotest.matchers.shouldBe 6 | 7 | class TArrayTest : ArrowFxSpec( 8 | spec = { 9 | "creating an array" { 10 | val t1 = TArray.new(10) { it } 11 | t1.size() shouldBeExactly 10 12 | atomically { t1.fold(0) { acc, v -> acc + v } } shouldBeExactly (0..9).sum() 13 | atomically { (0..9).fold(true) { acc, v -> t1.get(v) == v && acc } } shouldBe true 14 | 15 | val t2 = atomically { newTArray(10) { it } } 16 | t2.size() shouldBeExactly 10 17 | atomically { t2.fold(0) { acc, v -> acc + v } } shouldBeExactly (0..9).sum() 18 | atomically { (0..9).fold(true) { acc, v -> t2.get(v) == v && acc } } shouldBe true 19 | } 20 | "get should get the correct value" { 21 | val t2 = atomically { newTArray(20) { it } } 22 | atomically { (0..19).fold(true) { acc, v -> t2.get(v) == v && acc } } shouldBe true 23 | } 24 | "write should write to the correct value" { 25 | val t2 = atomically { newTArray(20) { it } } 26 | atomically { t2.get(5) } shouldBeExactly 5 27 | atomically { t2[5] = 2 } 28 | atomically { t2.get(5) } shouldBeExactly 2 29 | } 30 | "transform should perform an operation on each element" { 31 | val t2 = atomically { newTArray(20) { it } } 32 | atomically { t2.transform { it * 2 } } 33 | atomically { t2.fold(0) { acc, v -> acc + v } } shouldBeExactly (0..19).sum() * 2 34 | } 35 | } 36 | ) 37 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/extensions/io/unsafeCancellableRun/IOUnsafeCancellableRun.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.extensions.io.unsafeCancellableRun 2 | 3 | import arrow.Kind 4 | import arrow.core.Either 5 | import arrow.fx.ForIO 6 | import arrow.fx.IO.Companion 7 | import arrow.fx.IODeprecation 8 | import arrow.fx.OnCancel 9 | import arrow.fx.extensions.IOUnsafeCancellableRun 10 | import arrow.unsafe 11 | import kotlin.Deprecated 12 | import kotlin.Function0 13 | import kotlin.Function1 14 | import kotlin.PublishedApi 15 | import kotlin.Suppress 16 | import kotlin.Throwable 17 | import kotlin.Unit 18 | import kotlin.jvm.JvmName 19 | 20 | /** 21 | * cached extension 22 | */ 23 | @PublishedApi() 24 | internal val unsafeCancellableRun_singleton: IOUnsafeCancellableRun = object : 25 | arrow.fx.extensions.IOUnsafeCancellableRun {} 26 | 27 | @JvmName("runNonBlockingCancellable") 28 | @Suppress( 29 | "UNCHECKED_CAST", 30 | "USELESS_CAST", 31 | "EXTENSION_SHADOWED_BY_MEMBER", 32 | "UNUSED_PARAMETER" 33 | ) 34 | @Deprecated(IODeprecation) 35 | suspend fun unsafe.runNonBlockingCancellable( 36 | onCancel: OnCancel, 37 | fa: Function0>, 38 | cb: Function1, Unit> 39 | ): Function0 = arrow.fx.IO.unsafeCancellableRun().run { 40 | this@runNonBlockingCancellable.runNonBlockingCancellable(onCancel, fa, cb) as 41 | kotlin.Function0 42 | } 43 | 44 | @Suppress( 45 | "UNCHECKED_CAST", 46 | "NOTHING_TO_INLINE" 47 | ) 48 | @Deprecated(IODeprecation) 49 | inline fun Companion.unsafeCancellableRun(): IOUnsafeCancellableRun = unsafeCancellableRun_singleton 50 | -------------------------------------------------------------------------------- /arrow-fx-rx2/src/main/kotlin/arrow/fx/rx2/extensions/singlek/concurrentEffect/SingleKConcurrentEffect.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.rx2.extensions.singlek.concurrentEffect 2 | 3 | import arrow.Kind 4 | import arrow.core.Either 5 | import arrow.fx.rx2.DeprecateRxJava 6 | import arrow.fx.rx2.ForSingleK 7 | import arrow.fx.rx2.SingleK 8 | import arrow.fx.rx2.SingleK.Companion 9 | import arrow.fx.rx2.extensions.SingleKConcurrentEffect 10 | import kotlin.Deprecated 11 | import kotlin.Function0 12 | import kotlin.Function1 13 | import kotlin.PublishedApi 14 | import kotlin.Suppress 15 | import kotlin.Throwable 16 | import kotlin.Unit 17 | import kotlin.jvm.JvmName 18 | 19 | /** 20 | * cached extension 21 | */ 22 | @PublishedApi() 23 | internal val concurrentEffect_singleton: SingleKConcurrentEffect = object : 24 | arrow.fx.rx2.extensions.SingleKConcurrentEffect {} 25 | 26 | @JvmName("runAsyncCancellable") 27 | @Suppress( 28 | "UNCHECKED_CAST", 29 | "USELESS_CAST", 30 | "EXTENSION_SHADOWED_BY_MEMBER", 31 | "UNUSED_PARAMETER" 32 | ) 33 | @Deprecated(DeprecateRxJava) 34 | fun Kind.runAsyncCancellable( 35 | arg1: Function1, 36 | Kind> 37 | ): SingleK> = 38 | arrow.fx.rx2.SingleK.concurrentEffect().run { 39 | this@runAsyncCancellable.runAsyncCancellable(arg1) as 40 | arrow.fx.rx2.SingleK> 41 | } 42 | 43 | @Suppress( 44 | "UNCHECKED_CAST", 45 | "NOTHING_TO_INLINE" 46 | ) 47 | @Deprecated(DeprecateRxJava) 48 | inline fun Companion.concurrentEffect(): SingleKConcurrentEffect = concurrentEffect_singleton 49 | -------------------------------------------------------------------------------- /arrow-fx-reactor/src/main/kotlin/arrow/fx/reactor/extensions/fluxk/concurrentEffect/FluxKConcurrentEffect.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.reactor.extensions.fluxk.concurrentEffect 2 | 3 | import arrow.Kind 4 | import arrow.core.Either 5 | import arrow.fx.reactor.DeprecateReactor 6 | import arrow.fx.reactor.FluxK 7 | import arrow.fx.reactor.FluxK.Companion 8 | import arrow.fx.reactor.ForFluxK 9 | import arrow.fx.reactor.extensions.FluxKConcurrentEffect 10 | import kotlin.Deprecated 11 | import kotlin.Function0 12 | import kotlin.Function1 13 | import kotlin.PublishedApi 14 | import kotlin.Suppress 15 | import kotlin.Throwable 16 | import kotlin.Unit 17 | import kotlin.jvm.JvmName 18 | 19 | /** 20 | * cached extension 21 | */ 22 | @PublishedApi() 23 | internal val concurrentEffect_singleton: FluxKConcurrentEffect = object : 24 | arrow.fx.reactor.extensions.FluxKConcurrentEffect {} 25 | 26 | @JvmName("runAsyncCancellable") 27 | @Suppress( 28 | "UNCHECKED_CAST", 29 | "USELESS_CAST", 30 | "EXTENSION_SHADOWED_BY_MEMBER", 31 | "UNUSED_PARAMETER" 32 | ) 33 | @Deprecated(DeprecateReactor) 34 | fun Kind.runAsyncCancellable( 35 | arg1: Function1, Kind> 37 | ): FluxK> = arrow.fx.reactor.FluxK.concurrentEffect().run { 38 | this@runAsyncCancellable.runAsyncCancellable(arg1) as 39 | arrow.fx.reactor.FluxK> 40 | } 41 | 42 | @Suppress( 43 | "UNCHECKED_CAST", 44 | "NOTHING_TO_INLINE" 45 | ) 46 | @Deprecated(DeprecateReactor) 47 | inline fun Companion.concurrentEffect(): FluxKConcurrentEffect = concurrentEffect_singleton 48 | -------------------------------------------------------------------------------- /arrow-fx-reactor/src/main/kotlin/arrow/fx/reactor/extensions/monok/concurrentEffect/MonoKConcurrentEffect.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.reactor.extensions.monok.concurrentEffect 2 | 3 | import arrow.Kind 4 | import arrow.core.Either 5 | import arrow.fx.reactor.DeprecateReactor 6 | import arrow.fx.reactor.ForMonoK 7 | import arrow.fx.reactor.MonoK 8 | import arrow.fx.reactor.MonoK.Companion 9 | import arrow.fx.reactor.extensions.MonoKConcurrentEffect 10 | import kotlin.Deprecated 11 | import kotlin.Function0 12 | import kotlin.Function1 13 | import kotlin.PublishedApi 14 | import kotlin.Suppress 15 | import kotlin.Throwable 16 | import kotlin.Unit 17 | import kotlin.jvm.JvmName 18 | 19 | /** 20 | * cached extension 21 | */ 22 | @PublishedApi() 23 | internal val concurrentEffect_singleton: MonoKConcurrentEffect = object : 24 | arrow.fx.reactor.extensions.MonoKConcurrentEffect {} 25 | 26 | @JvmName("runAsyncCancellable") 27 | @Suppress( 28 | "UNCHECKED_CAST", 29 | "USELESS_CAST", 30 | "EXTENSION_SHADOWED_BY_MEMBER", 31 | "UNUSED_PARAMETER" 32 | ) 33 | @Deprecated(DeprecateReactor) 34 | fun Kind.runAsyncCancellable( 35 | arg1: Function1, Kind> 37 | ): MonoK> = arrow.fx.reactor.MonoK.concurrentEffect().run { 38 | this@runAsyncCancellable.runAsyncCancellable(arg1) as 39 | arrow.fx.reactor.MonoK> 40 | } 41 | 42 | @Suppress( 43 | "UNCHECKED_CAST", 44 | "NOTHING_TO_INLINE" 45 | ) 46 | @Deprecated(DeprecateReactor) 47 | inline fun Companion.concurrentEffect(): MonoKConcurrentEffect = concurrentEffect_singleton 48 | -------------------------------------------------------------------------------- /arrow-fx-rx2/src/main/kotlin/arrow/fx/rx2/extensions/dispatchers.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.rx2.extensions 2 | 3 | import arrow.fx.rx2.DeprecateRxJava 4 | import io.reactivex.Scheduler 5 | import io.reactivex.schedulers.Schedulers 6 | import kotlin.coroutines.AbstractCoroutineContextElement 7 | import kotlin.coroutines.Continuation 8 | import kotlin.coroutines.ContinuationInterceptor 9 | import kotlin.coroutines.CoroutineContext 10 | 11 | internal val ComputationScheduler: CoroutineContext = 12 | Schedulers.computation().asCoroutineContext() 13 | 14 | internal val IOScheduler: CoroutineContext = 15 | Schedulers.io().asCoroutineContext() 16 | 17 | @Deprecated(DeprecateRxJava) 18 | fun Scheduler.asCoroutineContext(): CoroutineContext = 19 | SchedulerContext(this) 20 | 21 | private class SchedulerContext(val scheduler: Scheduler) : AbstractCoroutineContextElement(ContinuationInterceptor), ContinuationInterceptor { 22 | override fun interceptContinuation(continuation: Continuation): Continuation = 23 | SchedulerContinuation( 24 | scheduler, 25 | continuation.context.fold(continuation) { cont, element -> 26 | if (element != this@SchedulerContext && element is ContinuationInterceptor) 27 | element.interceptContinuation(cont) else cont 28 | } 29 | ) 30 | } 31 | 32 | private class SchedulerContinuation( 33 | val scheduler: Scheduler, 34 | val cont: Continuation 35 | ) : Continuation { 36 | override val context: CoroutineContext = cont.context 37 | 38 | override fun resumeWith(result: Result) { 39 | scheduler.scheduleDirect { cont.resumeWith(result) } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /arrow-fx-rx2/src/main/kotlin/arrow/fx/rx2/extensions/flowablek/concurrentEffect/FlowableKConcurrentEffect.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.rx2.extensions.flowablek.concurrentEffect 2 | 3 | import arrow.Kind 4 | import arrow.core.Either 5 | import arrow.fx.rx2.DeprecateRxJava 6 | import arrow.fx.rx2.FlowableK 7 | import arrow.fx.rx2.FlowableK.Companion 8 | import arrow.fx.rx2.ForFlowableK 9 | import arrow.fx.rx2.extensions.FlowableKConcurrentEffect 10 | import kotlin.Deprecated 11 | import kotlin.Function0 12 | import kotlin.Function1 13 | import kotlin.PublishedApi 14 | import kotlin.Suppress 15 | import kotlin.Throwable 16 | import kotlin.Unit 17 | import kotlin.jvm.JvmName 18 | 19 | /** 20 | * cached extension 21 | */ 22 | @PublishedApi() 23 | internal val concurrentEffect_singleton: FlowableKConcurrentEffect = object : 24 | arrow.fx.rx2.extensions.FlowableKConcurrentEffect {} 25 | 26 | @JvmName("runAsyncCancellable") 27 | @Suppress( 28 | "UNCHECKED_CAST", 29 | "USELESS_CAST", 30 | "EXTENSION_SHADOWED_BY_MEMBER", 31 | "UNUSED_PARAMETER" 32 | ) 33 | @Deprecated(DeprecateRxJava) 34 | fun Kind.runAsyncCancellable( 35 | arg1: Function1, 36 | Kind> 37 | ): FlowableK> = 38 | arrow.fx.rx2.FlowableK.concurrentEffect().run { 39 | this@runAsyncCancellable.runAsyncCancellable(arg1) as 40 | arrow.fx.rx2.FlowableK> 41 | } 42 | 43 | @Suppress( 44 | "UNCHECKED_CAST", 45 | "NOTHING_TO_INLINE" 46 | ) 47 | @Deprecated(DeprecateRxJava) 48 | inline fun Companion.concurrentEffect(): FlowableKConcurrentEffect = concurrentEffect_singleton 49 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/extensions/QueueInvariant.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.extensions 2 | 3 | import arrow.Kind 4 | import arrow.core.Option 5 | import arrow.fx.IODeprecation 6 | import arrow.fx.Queue 7 | import arrow.fx.QueueOf 8 | import arrow.fx.QueuePartialOf 9 | import arrow.fx.fix 10 | import arrow.typeclasses.Functor 11 | import arrow.typeclasses.Invariant 12 | import arrow.undocumented 13 | 14 | @undocumented 15 | @Deprecated(IODeprecation) 16 | interface QueueInvariant : Invariant> { 17 | fun FR(): Functor 18 | 19 | override fun QueueOf.imap(f: (A) -> B, g: (B) -> A): Queue = 20 | FR().run { 21 | val fixed = this@imap.fix() 22 | object : Queue { 23 | override fun tryOfferAll(a: Iterable): Kind = fixed.tryOfferAll(a.map(g)) 24 | override fun offerAll(a: Iterable): Kind = fixed.offerAll(a.map(g)) 25 | override fun peek(): Kind = fixed.peek().map(f) 26 | override fun take(): Kind = fixed.take().map(f) 27 | override fun takeAll(): Kind> = fixed.takeAll().map { it.map(f) } 28 | override fun offer(a: B): Kind = fixed.offer(g(a)) 29 | override fun size(): Kind = fixed.size() 30 | override fun tryTake(): Kind> = fixed.tryTake().map { it.map(f) } 31 | override fun tryPeek(): Kind> = fixed.tryPeek().map { it.map(f) } 32 | override fun peekAll(): Kind> = fixed.peekAll().map { it.map(f) } 33 | override fun tryOffer(a: B): Kind = fixed.tryOffer(g(a)) 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /arrow-fx-rx2/src/main/kotlin/arrow/fx/rx2/extensions/observablek/concurrentEffect/ObservableKConcurrentEffect.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.rx2.extensions.observablek.concurrentEffect 2 | 3 | import arrow.Kind 4 | import arrow.core.Either 5 | import arrow.fx.rx2.DeprecateRxJava 6 | import arrow.fx.rx2.ForObservableK 7 | import arrow.fx.rx2.ObservableK 8 | import arrow.fx.rx2.ObservableK.Companion 9 | import arrow.fx.rx2.extensions.ObservableKConcurrentEffect 10 | import kotlin.Deprecated 11 | import kotlin.Function0 12 | import kotlin.Function1 13 | import kotlin.PublishedApi 14 | import kotlin.Suppress 15 | import kotlin.Throwable 16 | import kotlin.Unit 17 | import kotlin.jvm.JvmName 18 | 19 | /** 20 | * cached extension 21 | */ 22 | @PublishedApi() 23 | internal val concurrentEffect_singleton: ObservableKConcurrentEffect = object : 24 | arrow.fx.rx2.extensions.ObservableKConcurrentEffect {} 25 | 26 | @JvmName("runAsyncCancellable") 27 | @Suppress( 28 | "UNCHECKED_CAST", 29 | "USELESS_CAST", 30 | "EXTENSION_SHADOWED_BY_MEMBER", 31 | "UNUSED_PARAMETER" 32 | ) 33 | @Deprecated(DeprecateRxJava) 34 | fun Kind.runAsyncCancellable( 35 | arg1: Function1, 36 | Kind> 37 | ): ObservableK> = 38 | arrow.fx.rx2.ObservableK.concurrentEffect().run { 39 | this@runAsyncCancellable.runAsyncCancellable(arg1) as 40 | arrow.fx.rx2.ObservableK> 41 | } 42 | 43 | @Suppress( 44 | "UNCHECKED_CAST", 45 | "NOTHING_TO_INLINE" 46 | ) 47 | @Deprecated(DeprecateRxJava) 48 | inline fun Companion.concurrentEffect(): ObservableKConcurrentEffect = concurrentEffect_singleton 49 | -------------------------------------------------------------------------------- /arrow-docs/src/main/kotlin/DivideHelper.kt: -------------------------------------------------------------------------------- 1 | package com.example.domain 2 | 3 | import arrow.Kind 4 | import arrow.core.Either 5 | import arrow.core.Tuple2 6 | import arrow.higherkind 7 | import arrow.typeclasses.Decidable 8 | import arrow.typeclasses.Divide 9 | import arrow.typeclasses.Divisible 10 | 11 | @higherkind 12 | class Serializer(val func: (A) -> String) : Kind { 13 | companion object { 14 | fun divide() = object : SerializerDivide {} 15 | fun divisible() = object : SerializerDivisible {} 16 | fun decidable() = object : SerializerDecidable {} 17 | } 18 | } 19 | 20 | interface SerializerDivide : Divide { 21 | override fun Kind.contramap(f: (B) -> A): Kind = 22 | Serializer { this@contramap.fix().func(f(it)) } 23 | 24 | override fun divide(fa: Kind, fb: Kind, f: (Z) -> Tuple2) = 25 | Serializer { z: Z -> 26 | val (a, b) = f(z) 27 | "A: ${fa.fix().func(a)}; B: ${fb.fix().func(b)}" 28 | } 29 | } 30 | 31 | interface SerializerDivisible : Divisible, SerializerDivide { 32 | override fun conquer(): Kind = Serializer { "EMPTY" } 33 | } 34 | 35 | interface SerializerDecidable : Decidable, SerializerDivisible { 36 | override fun choose(fa: Kind, fb: Kind, f: (Z) -> Either): Kind = 37 | Serializer { 38 | f(it).fold( 39 | { 40 | "LEFT: " + fa.fix().func(it) 41 | }, 42 | { 43 | "RIGHT: " + fb.fix().func(it) 44 | } 45 | ) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /arrow-fx-coroutines/src/test/kotlin/arrow/fx/coroutines/GuaranteeCaseTest.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.coroutines 2 | 3 | import arrow.core.Either 4 | import io.kotest.matchers.shouldBe 5 | import io.kotest.matchers.types.shouldBeInstanceOf 6 | import io.kotest.property.Arb 7 | import io.kotest.property.arbitrary.int 8 | 9 | class GuaranteeCaseTest : ArrowFxSpec( 10 | spec = { 11 | 12 | "release for success was invoked" { 13 | checkAll(Arb.int()) { i -> 14 | val p = Promise() 15 | 16 | val res = guaranteeCase( 17 | fa = { i }, 18 | finalizer = { ex -> p.complete(ex) } 19 | ) 20 | 21 | p.get() shouldBe ExitCase.Completed 22 | res shouldBe i 23 | } 24 | } 25 | 26 | "release for error was invoked" { 27 | checkAll(Arb.throwable()) { e -> 28 | val p = Promise() 29 | val attempted = Either.catch { 30 | guaranteeCase( 31 | fa = { throw e }, 32 | finalizer = { ex -> p.complete(ex) } 33 | ) 34 | } 35 | 36 | p.get() shouldBe ExitCase.Failure(e) 37 | attempted shouldBe Either.Left(e) 38 | } 39 | } 40 | 41 | "release for never was invoked" { 42 | val p = Promise() 43 | val start = Promise() 44 | 45 | val fiber = ForkAndForget { 46 | guaranteeCase( 47 | fa = { 48 | start.complete(Unit) 49 | never() 50 | }, 51 | finalizer = { ex -> p.complete(ex) } 52 | ) 53 | } 54 | 55 | start.get() 56 | fiber.cancel() 57 | p.get().shouldBeInstanceOf() 58 | } 59 | } 60 | ) 61 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/src/jmh/kotlin/arrow/benchmarks/AttemptRaisedError.kt: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks 2 | 3 | import arrow.fx.IO 4 | import org.openjdk.jmh.annotations.Benchmark 5 | import org.openjdk.jmh.annotations.CompilerControl 6 | import org.openjdk.jmh.annotations.Fork 7 | import org.openjdk.jmh.annotations.Measurement 8 | import org.openjdk.jmh.annotations.Param 9 | import org.openjdk.jmh.annotations.Scope 10 | import org.openjdk.jmh.annotations.State 11 | import org.openjdk.jmh.annotations.Warmup 12 | import java.util.concurrent.TimeUnit 13 | 14 | val dummy = object : RuntimeException("dummy") { 15 | override fun fillInStackTrace(): Throwable = 16 | this 17 | } 18 | 19 | @State(Scope.Thread) 20 | @Fork(2) 21 | @Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS) 22 | @Measurement(iterations = 10) 23 | @CompilerControl(CompilerControl.Mode.DONT_INLINE) 24 | open class AttemptRaisedError { 25 | 26 | @Param("10000") 27 | var size: Int = 0 28 | 29 | private fun ioLoopNotHappy(size: Int, i: Int): IO = 30 | if (i < size) { 31 | IO { throw dummy }.attempt().flatMap { 32 | it.fold({ ioLoopNotHappy(size, i + 1) }, IO.Companion::just) 33 | } 34 | } else IO.just(1) 35 | 36 | @Benchmark 37 | fun io(): Int = 38 | ioLoopNotHappy(size, 0).unsafeRunSync() 39 | 40 | @Benchmark 41 | fun cats(): Any = 42 | arrow.benchmarks.effects.scala.cats.AttemptRaisedError.ioLoopNotHappy(size, 0).unsafeRunSync() 43 | 44 | @Benchmark 45 | fun zio(): Any = 46 | arrow.benchmarks.effects.scala.zio.AttemptRaisedError.run(size) 47 | 48 | @Benchmark 49 | fun kio(): Any = 50 | arrow.benchmarks.effects.kio.AttemptRaisedError.attemptRaisedError(size) 51 | } 52 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/extensions/io/unsafeRun/IOUnsafeRun.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.extensions.io.unsafeRun 2 | 3 | import arrow.Kind 4 | import arrow.core.Either 5 | import arrow.fx.ForIO 6 | import arrow.fx.IO.Companion 7 | import arrow.fx.IODeprecation 8 | import arrow.fx.extensions.IOUnsafeRun 9 | import arrow.unsafe 10 | import kotlin.Deprecated 11 | import kotlin.Function0 12 | import kotlin.Function1 13 | import kotlin.PublishedApi 14 | import kotlin.Suppress 15 | import kotlin.Throwable 16 | import kotlin.Unit 17 | import kotlin.jvm.JvmName 18 | 19 | /** 20 | * cached extension 21 | */ 22 | @PublishedApi() 23 | internal val unsafeRun_singleton: IOUnsafeRun = object : arrow.fx.extensions.IOUnsafeRun {} 24 | 25 | @JvmName("runBlocking") 26 | @Suppress( 27 | "UNCHECKED_CAST", 28 | "USELESS_CAST", 29 | "EXTENSION_SHADOWED_BY_MEMBER", 30 | "UNUSED_PARAMETER" 31 | ) 32 | @Deprecated(IODeprecation) 33 | suspend fun unsafe.runBlocking(fa: Function0>): A = arrow.fx.IO.unsafeRun().run { 34 | this@runBlocking.runBlocking(fa) as A 35 | } 36 | 37 | @JvmName("runNonBlocking") 38 | @Suppress( 39 | "UNCHECKED_CAST", 40 | "USELESS_CAST", 41 | "EXTENSION_SHADOWED_BY_MEMBER", 42 | "UNUSED_PARAMETER" 43 | ) 44 | @Deprecated(IODeprecation) 45 | suspend fun unsafe.runNonBlocking( 46 | fa: Function0>, 47 | cb: Function1, Unit> 49 | ): Unit = arrow.fx.IO.unsafeRun().run { 50 | this@runNonBlocking.runNonBlocking(fa, cb) as kotlin.Unit 51 | } 52 | 53 | @Suppress( 54 | "UNCHECKED_CAST", 55 | "NOTHING_TO_INLINE" 56 | ) 57 | @Deprecated(IODeprecation) 58 | inline fun Companion.unsafeRun(): IOUnsafeRun = unsafeRun_singleton 59 | -------------------------------------------------------------------------------- /arrow-benchmarks-fx/src/jmh/kotlin/arrow/benchmarks/Queue.kt: -------------------------------------------------------------------------------- 1 | package arrow.benchmarks 2 | 3 | import arrow.fx.ForIO 4 | import arrow.fx.IO 5 | import arrow.fx.IOOf 6 | import arrow.fx.Queue 7 | import arrow.fx.extensions.io.concurrent.concurrent 8 | import arrow.fx.extensions.io.monad.flatMap 9 | import arrow.fx.fix 10 | import arrow.fx.void 11 | import org.openjdk.jmh.annotations.Benchmark 12 | import org.openjdk.jmh.annotations.CompilerControl 13 | import org.openjdk.jmh.annotations.Fork 14 | import org.openjdk.jmh.annotations.Level 15 | import org.openjdk.jmh.annotations.Measurement 16 | import org.openjdk.jmh.annotations.Param 17 | import org.openjdk.jmh.annotations.Scope 18 | import org.openjdk.jmh.annotations.Setup 19 | import org.openjdk.jmh.annotations.State 20 | import org.openjdk.jmh.annotations.Warmup 21 | import java.util.concurrent.TimeUnit 22 | import kotlin.properties.Delegates 23 | 24 | @State(Scope.Thread) 25 | @Fork(2) 26 | @Warmup(iterations = 5, time = 2, timeUnit = TimeUnit.SECONDS) 27 | @Measurement(iterations = 5) 28 | @CompilerControl(CompilerControl.Mode.DONT_INLINE) 29 | open class Queue { 30 | 31 | @Param("1000") 32 | var size: Int = 0 33 | 34 | var ConcurQueue by Delegates.notNull>() 35 | 36 | @Setup(Level.Trial) 37 | fun createQueues(): Unit { 38 | ConcurQueue = Queue.unbounded(IO.concurrent()).fix().unsafeRunSync() 39 | } 40 | 41 | fun IOOf.repeat(n: Int): IO = 42 | if (n < 1) fix() else flatMap { repeat(n - 1) } 43 | 44 | fun loop(q: Queue): Unit = 45 | q.offer(0).void().repeat(size).flatMap { 46 | q.take().void().repeat(size) 47 | }.unsafeRunSync() 48 | 49 | @Benchmark 50 | fun concurrentQueue(): Unit = loop(ConcurQueue) 51 | } 52 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/internal/UnsafePromise.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.internal 2 | 3 | import arrow.core.Either 4 | import arrow.fx.IODeprecation 5 | import kotlinx.atomicfu.AtomicRef 6 | import kotlinx.atomicfu.atomic 7 | 8 | @Deprecated(IODeprecation) 9 | class UnsafePromise { 10 | 11 | private sealed class State { 12 | object Empty : State() 13 | data class Waiting(val joiners: List<(Either) -> Unit>) : State() 14 | data class Full(val a: Either) : State() 15 | } 16 | 17 | private val state: AtomicRef> = atomic(State.Empty) 18 | 19 | fun get(cb: (Either) -> Unit) { 20 | tailrec fun go(): Unit = when (val oldState = state.value) { 21 | State.Empty -> if (state.compareAndSet(oldState, State.Waiting(listOf(cb)))) Unit else go() 22 | is State.Waiting -> if (state.compareAndSet(oldState, State.Waiting(oldState.joiners + cb))) Unit else go() 23 | is State.Full -> cb(oldState.a) 24 | } 25 | 26 | go() 27 | } 28 | 29 | fun complete(value: Either) { 30 | tailrec fun go(): Unit = when (val oldState = state.value) { 31 | State.Empty -> if (state.compareAndSet(oldState, State.Full(value))) Unit else go() 32 | is State.Waiting -> { 33 | if (state.compareAndSet(oldState, State.Full(value))) oldState.joiners.forEach { it(value) } 34 | else go() 35 | } 36 | is State.Full -> throw ArrowInternalException() 37 | } 38 | 39 | go() 40 | } 41 | 42 | fun remove(cb: (Either) -> Unit) = when (val oldState = state.value) { 43 | State.Empty -> Unit 44 | is State.Waiting -> state.value = State.Waiting(oldState.joiners - cb) 45 | is State.Full -> Unit 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /arrow-fx-rx2/src/main/kotlin/arrow/fx/rx2/extensions/maybek/monadFilter/MaybeKMonadFilter.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.rx2.extensions.maybek.monadFilter 2 | 3 | import arrow.Kind 4 | import arrow.core.Option 5 | import arrow.fx.rx2.DeprecateRxJava 6 | import arrow.fx.rx2.ForMaybeK 7 | import arrow.fx.rx2.MaybeK 8 | import arrow.fx.rx2.MaybeK.Companion 9 | import arrow.fx.rx2.extensions.MaybeKMonadFilter 10 | import arrow.typeclasses.MonadFilterSyntax 11 | import kotlin.Deprecated 12 | import kotlin.Function1 13 | import kotlin.PublishedApi 14 | import kotlin.Suppress 15 | import kotlin.jvm.JvmName 16 | 17 | /** 18 | * cached extension 19 | */ 20 | @PublishedApi() 21 | internal val monadFilter_singleton: MaybeKMonadFilter = object : 22 | arrow.fx.rx2.extensions.MaybeKMonadFilter {} 23 | 24 | @JvmName("filterMap") 25 | @Suppress( 26 | "UNCHECKED_CAST", 27 | "USELESS_CAST", 28 | "EXTENSION_SHADOWED_BY_MEMBER", 29 | "UNUSED_PARAMETER" 30 | ) 31 | @Deprecated(DeprecateRxJava) 32 | fun Kind.filterMap(arg1: Function1>): MaybeK = 33 | arrow.fx.rx2.MaybeK.monadFilter().run { 34 | this@filterMap.filterMap(arg1) as arrow.fx.rx2.MaybeK 35 | } 36 | 37 | @JvmName("bindingFilter") 38 | @Suppress( 39 | "UNCHECKED_CAST", 40 | "USELESS_CAST", 41 | "EXTENSION_SHADOWED_BY_MEMBER", 42 | "UNUSED_PARAMETER" 43 | ) 44 | @Deprecated(DeprecateRxJava) 45 | fun bindingFilter(arg0: suspend MonadFilterSyntax.() -> B): MaybeK = 46 | arrow.fx.rx2.MaybeK 47 | .monadFilter() 48 | .bindingFilter(arg0) as arrow.fx.rx2.MaybeK 49 | 50 | @Suppress( 51 | "UNCHECKED_CAST", 52 | "NOTHING_TO_INLINE" 53 | ) 54 | @Deprecated(DeprecateRxJava) 55 | inline fun Companion.monadFilter(): MaybeKMonadFilter = monadFilter_singleton 56 | -------------------------------------------------------------------------------- /arrow-fx-coroutines/src/test/kotlin/arrow/fx/coroutines/ForwardCancelableTests.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.coroutines 2 | 3 | import io.kotest.assertions.throwables.shouldThrow 4 | import io.kotest.matchers.shouldBe 5 | import kotlin.coroutines.Continuation 6 | import kotlin.coroutines.EmptyCoroutineContext 7 | import kotlin.coroutines.startCoroutine 8 | 9 | class ForwardCancelableTests : ArrowFxSpec( 10 | spec = { 11 | "cancel() after complete" { 12 | var effect = 0 13 | 14 | val ref = ForwardCancellable(coroutineContext) 15 | ref.complete(CancelToken { effect += 1 }) 16 | effect shouldBe 0 17 | 18 | ref.cancel() 19 | effect shouldBe 1 20 | 21 | // Weak idempotency guarantees (not thread-safe) 22 | ref.cancel() 23 | effect shouldBe 1 24 | } 25 | 26 | "cancel() before complete" { 27 | var effect = 0 28 | 29 | val ref = ForwardCancellable(coroutineContext) 30 | ref::cancel.startCoroutine(Continuation(EmptyCoroutineContext) { }) 31 | effect shouldBe 0 32 | 33 | ref.complete(CancelToken { effect += 1 }) 34 | effect shouldBe 1 35 | 36 | shouldThrow { ref.complete(CancelToken { effect += 2 }) } 37 | // completed task was canceled before error was thrown 38 | effect shouldBe 3 39 | 40 | ref.cancel() 41 | effect shouldBe 3 42 | } 43 | 44 | "complete twice before cancel" { 45 | var effect = 0 46 | 47 | val ref = ForwardCancellable(coroutineContext) 48 | ref.complete(CancelToken { effect += 1 }) 49 | effect shouldBe 0 50 | 51 | shouldThrow { ref.complete(CancelToken { effect += 2 }) } 52 | effect shouldBe 2 53 | 54 | ref.cancel() 55 | effect shouldBe 3 56 | } 57 | } 58 | ) 59 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/extensions/schedule/semigroup/ScheduleSemigroup.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.extensions.schedule.semigroup 2 | 3 | import arrow.fx.IODeprecation 4 | import arrow.fx.Schedule 5 | import arrow.fx.Schedule.Companion 6 | import arrow.fx.extensions.ScheduleSemigroup 7 | import arrow.typeclasses.Semigroup 8 | import kotlin.Deprecated 9 | import kotlin.Suppress 10 | import kotlin.jvm.JvmName 11 | 12 | @JvmName("plus") 13 | @Suppress( 14 | "UNCHECKED_CAST", 15 | "USELESS_CAST", 16 | "EXTENSION_SHADOWED_BY_MEMBER", 17 | "UNUSED_PARAMETER" 18 | ) 19 | @Deprecated(IODeprecation) 20 | fun Schedule.plus( 21 | OI: Semigroup, 22 | arg1: Schedule 24 | ): Schedule = arrow.fx.Schedule.semigroup(OI).run { 26 | this@plus.plus(arg1) as arrow.fx.Schedule 27 | } 28 | 29 | @JvmName("maybeCombine") 30 | @Suppress( 31 | "UNCHECKED_CAST", 32 | "USELESS_CAST", 33 | "EXTENSION_SHADOWED_BY_MEMBER", 34 | "UNUSED_PARAMETER" 35 | ) 36 | @Deprecated(IODeprecation) 37 | fun Schedule.maybeCombine( 38 | OI: Semigroup, 39 | arg1: Schedule 40 | ): Schedule = arrow.fx.Schedule.semigroup(OI).run { 42 | this@maybeCombine.maybeCombine(arg1) as arrow.fx.Schedule 43 | } 44 | 45 | @Suppress( 46 | "UNCHECKED_CAST", 47 | "NOTHING_TO_INLINE" 48 | ) 49 | @Deprecated(IODeprecation) 50 | inline fun Companion.semigroup(OI: Semigroup): ScheduleSemigroup = object : arrow.fx.extensions.ScheduleSemigroup { 52 | override fun 53 | OI(): arrow.typeclasses.Semigroup = OI 54 | } 55 | -------------------------------------------------------------------------------- /arrow-fx-reactor/src/main/kotlin/arrow/fx/reactor/extensions/fluxk/monadFilter/FluxKMonadFilter.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.reactor.extensions.fluxk.monadFilter 2 | 3 | import arrow.Kind 4 | import arrow.core.Option 5 | import arrow.fx.reactor.DeprecateReactor 6 | import arrow.fx.reactor.FluxK 7 | import arrow.fx.reactor.FluxK.Companion 8 | import arrow.fx.reactor.ForFluxK 9 | import arrow.fx.reactor.extensions.FluxKMonadFilter 10 | import arrow.typeclasses.MonadFilterSyntax 11 | import kotlin.Deprecated 12 | import kotlin.Function1 13 | import kotlin.PublishedApi 14 | import kotlin.Suppress 15 | import kotlin.jvm.JvmName 16 | 17 | /** 18 | * cached extension 19 | */ 20 | @PublishedApi() 21 | internal val monadFilter_singleton: FluxKMonadFilter = object : 22 | arrow.fx.reactor.extensions.FluxKMonadFilter {} 23 | 24 | @JvmName("filterMap") 25 | @Suppress( 26 | "UNCHECKED_CAST", 27 | "USELESS_CAST", 28 | "EXTENSION_SHADOWED_BY_MEMBER", 29 | "UNUSED_PARAMETER" 30 | ) 31 | @Deprecated(DeprecateReactor) 32 | fun Kind.filterMap(arg1: Function1>): FluxK = 33 | arrow.fx.reactor.FluxK.monadFilter().run { 34 | this@filterMap.filterMap(arg1) as arrow.fx.reactor.FluxK 35 | } 36 | 37 | @JvmName("bindingFilter") 38 | @Suppress( 39 | "UNCHECKED_CAST", 40 | "USELESS_CAST", 41 | "EXTENSION_SHADOWED_BY_MEMBER", 42 | "UNUSED_PARAMETER" 43 | ) 44 | @Deprecated(DeprecateReactor) 45 | fun bindingFilter(arg0: suspend MonadFilterSyntax.() -> B): FluxK = 46 | arrow.fx.reactor.FluxK 47 | .monadFilter() 48 | .bindingFilter(arg0) as arrow.fx.reactor.FluxK 49 | 50 | @Suppress( 51 | "UNCHECKED_CAST", 52 | "NOTHING_TO_INLINE" 53 | ) 54 | @Deprecated(DeprecateReactor) 55 | inline fun Companion.monadFilter(): FluxKMonadFilter = monadFilter_singleton 56 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/extensions/resource/monoid/ResourceMonoid.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.extensions.resource.monoid 2 | 3 | import arrow.fx.IODeprecation 4 | import arrow.fx.Resource 5 | import arrow.fx.Resource.Companion 6 | import arrow.fx.extensions.ResourceMonoid 7 | import arrow.fx.typeclasses.Bracket 8 | import arrow.typeclasses.Monoid 9 | import kotlin.Deprecated 10 | import kotlin.Suppress 11 | import kotlin.collections.Collection 12 | import kotlin.collections.List 13 | import kotlin.jvm.JvmName 14 | 15 | @JvmName("combineAll") 16 | @Suppress( 17 | "UNCHECKED_CAST", 18 | "USELESS_CAST", 19 | "EXTENSION_SHADOWED_BY_MEMBER", 20 | "UNUSED_PARAMETER" 21 | ) 22 | @Deprecated(IODeprecation) 23 | fun Collection>.combineAll(MR: Monoid, BR: Bracket): 24 | Resource = arrow.fx.Resource.monoid(MR, BR).run { 25 | this@combineAll.combineAll() as arrow.fx.Resource 26 | } 27 | 28 | @JvmName("combineAll") 29 | @Suppress( 30 | "UNCHECKED_CAST", 31 | "USELESS_CAST", 32 | "EXTENSION_SHADOWED_BY_MEMBER", 33 | "UNUSED_PARAMETER" 34 | ) 35 | @Deprecated(IODeprecation) 36 | fun combineAll( 37 | MR: Monoid, 38 | BR: Bracket, 39 | arg0: List> 40 | ): Resource = arrow.fx.Resource 41 | .monoid(MR, BR) 42 | .combineAll(arg0) as arrow.fx.Resource 43 | 44 | @Suppress( 45 | "UNCHECKED_CAST", 46 | "NOTHING_TO_INLINE" 47 | ) 48 | @Deprecated(IODeprecation) 49 | inline fun Companion.monoid(MR: Monoid, BR: Bracket): ResourceMonoid = 50 | object : arrow.fx.extensions.ResourceMonoid { 51 | override fun MR(): 52 | arrow.typeclasses.Monoid = MR 53 | 54 | override fun BR(): arrow.fx.typeclasses.Bracket = BR 55 | } 56 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/extensions/resource/semigroup/ResourceSemigroup.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.extensions.resource.semigroup 2 | 3 | import arrow.fx.IODeprecation 4 | import arrow.fx.Resource 5 | import arrow.fx.Resource.Companion 6 | import arrow.fx.extensions.ResourceSemigroup 7 | import arrow.fx.typeclasses.Bracket 8 | import arrow.typeclasses.Semigroup 9 | import kotlin.Deprecated 10 | import kotlin.Suppress 11 | import kotlin.jvm.JvmName 12 | 13 | @JvmName("plus") 14 | @Suppress( 15 | "UNCHECKED_CAST", 16 | "USELESS_CAST", 17 | "EXTENSION_SHADOWED_BY_MEMBER", 18 | "UNUSED_PARAMETER" 19 | ) 20 | @Deprecated(IODeprecation) 21 | fun Resource.plus( 22 | SR: Semigroup, 23 | BR: Bracket, 24 | arg1: Resource 25 | ): Resource = arrow.fx.Resource.semigroup(SR, BR).run { 26 | this@plus.plus(arg1) as arrow.fx.Resource 27 | } 28 | 29 | @JvmName("maybeCombine") 30 | @Suppress( 31 | "UNCHECKED_CAST", 32 | "USELESS_CAST", 33 | "EXTENSION_SHADOWED_BY_MEMBER", 34 | "UNUSED_PARAMETER" 35 | ) 36 | @Deprecated(IODeprecation) 37 | fun Resource.maybeCombine( 38 | SR: Semigroup, 39 | BR: Bracket, 40 | arg1: Resource 41 | ): Resource = arrow.fx.Resource.semigroup(SR, BR).run { 42 | this@maybeCombine.maybeCombine(arg1) as arrow.fx.Resource 43 | } 44 | 45 | @Suppress( 46 | "UNCHECKED_CAST", 47 | "NOTHING_TO_INLINE" 48 | ) 49 | @Deprecated(IODeprecation) 50 | inline fun Companion.semigroup(SR: Semigroup, BR: Bracket): ResourceSemigroup = object : arrow.fx.extensions.ResourceSemigroup { 52 | override fun SR(): 53 | arrow.typeclasses.Semigroup = SR 54 | 55 | override fun BR(): arrow.fx.typeclasses.Bracket = BR 56 | } 57 | -------------------------------------------------------------------------------- /arrow-fx-rx2/src/main/kotlin/arrow/fx/rx2/extensions/maybek/unsafeRun/MaybeKUnsafeRun.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.rx2.extensions.maybek.unsafeRun 2 | 3 | import arrow.Kind 4 | import arrow.core.Either 5 | import arrow.fx.rx2.DeprecateRxJava 6 | import arrow.fx.rx2.ForMaybeK 7 | import arrow.fx.rx2.MaybeK.Companion 8 | import arrow.fx.rx2.extensions.MaybeKUnsafeRun 9 | import arrow.unsafe 10 | import kotlin.Deprecated 11 | import kotlin.Function0 12 | import kotlin.Function1 13 | import kotlin.PublishedApi 14 | import kotlin.Suppress 15 | import kotlin.Throwable 16 | import kotlin.Unit 17 | import kotlin.jvm.JvmName 18 | 19 | /** 20 | * cached extension 21 | */ 22 | @PublishedApi() 23 | internal val unsafeRun_singleton: MaybeKUnsafeRun = object : arrow.fx.rx2.extensions.MaybeKUnsafeRun 24 | {} 25 | 26 | @JvmName("runBlocking") 27 | @Suppress( 28 | "UNCHECKED_CAST", 29 | "USELESS_CAST", 30 | "EXTENSION_SHADOWED_BY_MEMBER", 31 | "UNUSED_PARAMETER" 32 | ) 33 | @Deprecated(DeprecateRxJava) 34 | suspend fun unsafe.runBlocking(arg1: Function0>): A = 35 | arrow.fx.rx2.MaybeK.unsafeRun().run { 36 | this@runBlocking.runBlocking(arg1) as A 37 | } 38 | 39 | @JvmName("runNonBlocking") 40 | @Suppress( 41 | "UNCHECKED_CAST", 42 | "USELESS_CAST", 43 | "EXTENSION_SHADOWED_BY_MEMBER", 44 | "UNUSED_PARAMETER" 45 | ) 46 | @Deprecated(DeprecateRxJava) 47 | suspend fun unsafe.runNonBlocking( 48 | arg1: Function0>, 49 | arg2: Function1, Unit> 50 | ): Unit = arrow.fx.rx2.MaybeK.unsafeRun().run { 51 | this@runNonBlocking.runNonBlocking(arg1, arg2) as kotlin.Unit 52 | } 53 | 54 | @Suppress( 55 | "UNCHECKED_CAST", 56 | "NOTHING_TO_INLINE" 57 | ) 58 | @Deprecated(DeprecateRxJava) 59 | inline fun Companion.unsafeRun(): MaybeKUnsafeRun = unsafeRun_singleton 60 | -------------------------------------------------------------------------------- /arrow-fx-rx2/src/main/kotlin/arrow/fx/rx2/extensions/flowablek/monadFilter/FlowableKMonadFilter.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.rx2.extensions.flowablek.monadFilter 2 | 3 | import arrow.Kind 4 | import arrow.core.Option 5 | import arrow.fx.rx2.DeprecateRxJava 6 | import arrow.fx.rx2.FlowableK 7 | import arrow.fx.rx2.FlowableK.Companion 8 | import arrow.fx.rx2.ForFlowableK 9 | import arrow.fx.rx2.extensions.FlowableKMonadFilter 10 | import arrow.typeclasses.MonadFilterSyntax 11 | import kotlin.Deprecated 12 | import kotlin.Function1 13 | import kotlin.PublishedApi 14 | import kotlin.Suppress 15 | import kotlin.jvm.JvmName 16 | 17 | /** 18 | * cached extension 19 | */ 20 | @PublishedApi() 21 | internal val monadFilter_singleton: FlowableKMonadFilter = object : 22 | arrow.fx.rx2.extensions.FlowableKMonadFilter {} 23 | 24 | @JvmName("filterMap") 25 | @Suppress( 26 | "UNCHECKED_CAST", 27 | "USELESS_CAST", 28 | "EXTENSION_SHADOWED_BY_MEMBER", 29 | "UNUSED_PARAMETER" 30 | ) 31 | @Deprecated(DeprecateRxJava) 32 | fun Kind.filterMap(arg1: Function1>): FlowableK = 33 | arrow.fx.rx2.FlowableK.monadFilter().run { 34 | this@filterMap.filterMap(arg1) as arrow.fx.rx2.FlowableK 35 | } 36 | 37 | @JvmName("bindingFilter") 38 | @Suppress( 39 | "UNCHECKED_CAST", 40 | "USELESS_CAST", 41 | "EXTENSION_SHADOWED_BY_MEMBER", 42 | "UNUSED_PARAMETER" 43 | ) 44 | @Deprecated(DeprecateRxJava) 45 | fun bindingFilter(arg0: suspend MonadFilterSyntax.() -> B): FlowableK = 46 | arrow.fx.rx2.FlowableK 47 | .monadFilter() 48 | .bindingFilter(arg0) as arrow.fx.rx2.FlowableK 49 | 50 | @Suppress( 51 | "UNCHECKED_CAST", 52 | "NOTHING_TO_INLINE" 53 | ) 54 | @Deprecated(DeprecateRxJava) 55 | inline fun Companion.monadFilter(): FlowableKMonadFilter = monadFilter_singleton 56 | -------------------------------------------------------------------------------- /arrow-fx-rx2/src/main/kotlin/arrow/fx/rx2/extensions/singlek/unsafeRun/SingleKUnsafeRun.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.rx2.extensions.singlek.unsafeRun 2 | 3 | import arrow.Kind 4 | import arrow.core.Either 5 | import arrow.fx.rx2.DeprecateRxJava 6 | import arrow.fx.rx2.ForSingleK 7 | import arrow.fx.rx2.SingleK.Companion 8 | import arrow.fx.rx2.extensions.SingleKUnsafeRun 9 | import arrow.unsafe 10 | import kotlin.Deprecated 11 | import kotlin.Function0 12 | import kotlin.Function1 13 | import kotlin.PublishedApi 14 | import kotlin.Suppress 15 | import kotlin.Throwable 16 | import kotlin.Unit 17 | import kotlin.jvm.JvmName 18 | 19 | /** 20 | * cached extension 21 | */ 22 | @PublishedApi() 23 | internal val unsafeRun_singleton: SingleKUnsafeRun = object : 24 | arrow.fx.rx2.extensions.SingleKUnsafeRun {} 25 | 26 | @JvmName("runBlocking") 27 | @Suppress( 28 | "UNCHECKED_CAST", 29 | "USELESS_CAST", 30 | "EXTENSION_SHADOWED_BY_MEMBER", 31 | "UNUSED_PARAMETER" 32 | ) 33 | @Deprecated(DeprecateRxJava) 34 | suspend fun unsafe.runBlocking(arg1: Function0>): A = 35 | arrow.fx.rx2.SingleK.unsafeRun().run { 36 | this@runBlocking.runBlocking(arg1) as A 37 | } 38 | 39 | @JvmName("runNonBlocking") 40 | @Suppress( 41 | "UNCHECKED_CAST", 42 | "USELESS_CAST", 43 | "EXTENSION_SHADOWED_BY_MEMBER", 44 | "UNUSED_PARAMETER" 45 | ) 46 | @Deprecated(DeprecateRxJava) 47 | suspend fun unsafe.runNonBlocking( 48 | arg1: Function0>, 49 | arg2: Function1, Unit> 50 | ): Unit = arrow.fx.rx2.SingleK.unsafeRun().run { 51 | this@runNonBlocking.runNonBlocking(arg1, arg2) as kotlin.Unit 52 | } 53 | 54 | @Suppress( 55 | "UNCHECKED_CAST", 56 | "NOTHING_TO_INLINE" 57 | ) 58 | @Deprecated(DeprecateRxJava) 59 | inline fun Companion.unsafeRun(): SingleKUnsafeRun = unsafeRun_singleton 60 | -------------------------------------------------------------------------------- /arrow-fx-coroutines/src/main/kotlin/arrow/fx/coroutines/flow.kt: -------------------------------------------------------------------------------- 1 | @file:JvmMultifileClass 2 | @file:JvmName("FlowExtensions") 3 | 4 | package arrow.fx.coroutines 5 | 6 | import kotlinx.coroutines.delay 7 | import kotlinx.coroutines.flow.Flow 8 | import kotlinx.coroutines.flow.collect 9 | import kotlinx.coroutines.flow.flow 10 | import kotlinx.coroutines.flow.retryWhen 11 | 12 | /** 13 | * Retries collection of the given flow when an exception occurs in the upstream flow based on a decision by the [schedule]. 14 | * This operator is *transparent* to exceptions that occur in downstream flow and does not retry on exceptions that are thrown 15 | * to cancel the flow. 16 | * 17 | * @see [Schedule] for how to build a schedule. 18 | * 19 | * ```kotlin:ank:playground 20 | * import kotlinx.coroutines.flow.* 21 | * import arrow.fx.coroutines.* 22 | * suspend fun main(): Unit { 23 | * var counter = 0 24 | * val flow = flow { 25 | * emit(a) 26 | * if (++counter <= 5) throw RuntimeException("Bang!") 27 | * } 28 | * //sampleStart 29 | * val sum = flow.retry(Schedule.recurs(5)) 30 | * .reduce { acc, int -> acc + int } 31 | * //sampleEnd 32 | * println(result) 33 | * } 34 | * ``` 35 | * 36 | * @param schedule - the [Schedule] used for retrying the collection of the flow 37 | */ 38 | fun Flow.retry(schedule: Schedule): Flow = flow { 39 | (schedule as Schedule.ScheduleImpl) 40 | var dec: Schedule.Decision 41 | var state: Any? = schedule.initialState() 42 | 43 | val retryWhen = retryWhen { cause, _ -> 44 | dec = schedule.update(cause, state) 45 | state = dec.state 46 | 47 | if (dec.cont) { 48 | delay((dec.delayInNanos / 1_000_000).toLong()) 49 | true 50 | } else { 51 | false 52 | } 53 | } 54 | retryWhen.collect { 55 | emit(it) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /arrow-fx-test/src/main/kotlin/arrow/fx/test/generators/Generators.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.test.generators 2 | 3 | import arrow.Kind 4 | import arrow.core.Eval 5 | import arrow.core.test.generators.GenK 6 | import arrow.core.test.generators.intSmall 7 | import arrow.core.test.generators.throwable 8 | import arrow.fx.DecisionPartialOf 9 | import arrow.fx.ForIO 10 | import arrow.fx.IO 11 | import arrow.fx.Schedule 12 | import arrow.fx.typeclasses.Duration 13 | import arrow.fx.typeclasses.Fiber 14 | import arrow.fx.typeclasses.FiberPartialOf 15 | import arrow.fx.typeclasses.nanoseconds 16 | import arrow.typeclasses.Applicative 17 | import arrow.typeclasses.ApplicativeError 18 | import io.kotlintest.properties.Gen 19 | import java.util.concurrent.TimeUnit 20 | 21 | fun Gen.raiseError(AP: ApplicativeError): Gen> = 22 | map { AP.raiseError(it) } 23 | 24 | fun Gen.Companion.timeUnit(): Gen = Gen.from(TimeUnit.values()) 25 | 26 | fun duration(): Gen = 27 | Gen.bind(Gen.long(), Gen.timeUnit(), ::Duration) 28 | 29 | fun IO.Companion.genK() = object : GenK { 30 | override fun genK(gen: Gen): Gen> = Gen.oneOf( 31 | gen.map(IO.Companion::just), 32 | Gen.throwable().map(IO.Companion::raiseError) 33 | ) 34 | } 35 | 36 | fun Fiber.Companion.genK(A: Applicative) = object : GenK> { 37 | override fun genK(gen: Gen): Gen, A>> = gen.map { 38 | Fiber(A.just(it), A.just(Unit)) 39 | } 40 | } 41 | 42 | fun Schedule.Decision.Companion.genK(): GenK> = object : GenK> { 43 | override fun genK(gen: Gen): Gen, A>> = 44 | Gen.bind( 45 | Gen.bool(), 46 | Gen.intSmall(), 47 | gen 48 | ) { cont, delay, res -> Schedule.Decision(cont, delay.nanoseconds, 0 as Any?, Eval.now(res)) } 49 | } 50 | -------------------------------------------------------------------------------- /arrow-fx-rx2/src/main/kotlin/arrow/fx/rx2/CoroutineContextRx2Scheduler.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.rx2 2 | 3 | import arrow.typeclasses.Continuation 4 | import io.reactivex.Scheduler 5 | import io.reactivex.disposables.Disposable 6 | import io.reactivex.internal.disposables.EmptyDisposable 7 | import java.util.concurrent.TimeUnit 8 | import kotlin.coroutines.CoroutineContext 9 | import kotlin.coroutines.startCoroutine 10 | 11 | private interface NonCancellableContinuation : Continuation, Disposable 12 | 13 | @Deprecated(DeprecateRxJava) 14 | fun CoroutineContext.asScheduler(): Scheduler = 15 | object : Scheduler() { 16 | override fun createWorker(): Worker = 17 | object : Worker() { 18 | @Volatile 19 | var once = false 20 | 21 | override fun isDisposed(): Boolean = once 22 | 23 | override fun schedule(run: Runnable, delay: Long, unit: TimeUnit): Disposable { 24 | if (once) { 25 | return EmptyDisposable.INSTANCE 26 | } 27 | 28 | val a: suspend () -> Unit = { run.run() } 29 | val completion: NonCancellableContinuation = simpleContinuation(this@asScheduler) 30 | a.startCoroutine(completion) 31 | return completion 32 | } 33 | 34 | override fun dispose() { 35 | once = false 36 | } 37 | 38 | private fun simpleContinuation(context: CoroutineContext): NonCancellableContinuation = 39 | object : NonCancellableContinuation { 40 | override fun isDisposed(): Boolean = false 41 | 42 | override fun dispose() { 43 | } 44 | 45 | override val context: CoroutineContext = context 46 | 47 | override fun resume(value: Unit) { 48 | } 49 | 50 | override fun resumeWithException(exception: Throwable) { 51 | throw exception 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/internal/ConcurrentSleep.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.internal 2 | 3 | import arrow.Kind 4 | import arrow.core.Either 5 | import arrow.core.Left 6 | import arrow.core.Right 7 | import arrow.fx.typeclasses.Concurrent 8 | import arrow.fx.typeclasses.Duration 9 | import java.util.concurrent.Executors 10 | import java.util.concurrent.ScheduledExecutorService 11 | import kotlin.coroutines.Continuation 12 | import kotlin.coroutines.CoroutineContext 13 | import kotlin.coroutines.startCoroutine 14 | 15 | internal fun Concurrent.ConcurrentSleep(duration: Duration): Kind = cancellable { cb -> 16 | val cancelRef = scheduler.schedule(ShiftTick(dispatchers().default(), cb), duration.amount, duration.timeUnit) 17 | later { cancelRef.cancel(false); Unit } 18 | } 19 | 20 | /** 21 | * [scheduler] is **only** for internal use for the [Concurrent.sleep] implementation. 22 | * This way we can guarantee nothing besides sleeping ever occurs here. 23 | */ 24 | internal val scheduler: ScheduledExecutorService by lazy { 25 | Executors.newScheduledThreadPool(2) { r -> 26 | Thread(r).apply { 27 | name = "arrow-effect-scheduler-$id" 28 | isDaemon = true 29 | } 30 | } 31 | } 32 | 33 | /** 34 | * [ShiftTick] is a small utility to [Concurrent.shift] work away from the [ScheduledExecutorService]. 35 | * As mentioned in [scheduler] no work should ever happen there. 36 | * So after sleeping we need to shift away to not keep that thread occupied. 37 | */ 38 | internal class ShiftTick( 39 | private val ctx: CoroutineContext, 40 | private val cb: (Either) -> Unit 41 | ) : Runnable { 42 | override fun run() { 43 | suspend { Unit }.startCoroutine( 44 | Continuation(ctx) { 45 | it.fold({ unit -> cb(Right(unit)) }, { e -> cb(Left(e)) }) 46 | } 47 | ) 48 | } 49 | } 50 | 51 | class TimeoutException(override val message: String) : Exception() 52 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/extensions/schedule/monoid/ScheduleMonoid.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.extensions.schedule.monoid 2 | 3 | import arrow.fx.IODeprecation 4 | import arrow.fx.Schedule 5 | import arrow.fx.Schedule.Companion 6 | import arrow.fx.extensions.ScheduleMonoid 7 | import arrow.typeclasses.Monad 8 | import arrow.typeclasses.Monoid 9 | import kotlin.Deprecated 10 | import kotlin.Suppress 11 | import kotlin.collections.Collection 12 | import kotlin.collections.List 13 | import kotlin.jvm.JvmName 14 | 15 | @JvmName("combineAll") 16 | @Suppress( 17 | "UNCHECKED_CAST", 18 | "USELESS_CAST", 19 | "EXTENSION_SHADOWED_BY_MEMBER", 20 | "UNUSED_PARAMETER" 21 | ) 22 | @Deprecated(IODeprecation) 23 | fun Collection>.combineAll( 24 | OI: Monoid, 25 | MF: Monad 26 | ): Schedule = arrow.fx.Schedule.monoid(OI, MF).run { 28 | this@combineAll.combineAll() as arrow.fx.Schedule 29 | } 30 | 31 | @JvmName("combineAll") 32 | @Suppress( 33 | "UNCHECKED_CAST", 34 | "USELESS_CAST", 35 | "EXTENSION_SHADOWED_BY_MEMBER", 36 | "UNUSED_PARAMETER" 37 | ) 38 | @Deprecated(IODeprecation) 39 | fun combineAll( 40 | OI: Monoid, 41 | MF: Monad, 42 | arg0: List> 43 | ): Schedule = arrow.fx.Schedule 44 | .monoid(OI, MF) 45 | .combineAll(arg0) as arrow.fx.Schedule 46 | 47 | @Suppress( 48 | "UNCHECKED_CAST", 49 | "NOTHING_TO_INLINE" 50 | ) 51 | @Deprecated(IODeprecation) 52 | inline fun Companion.monoid(OI: Monoid, MF: Monad): ScheduleMonoid = object : arrow.fx.extensions.ScheduleMonoid { 54 | override fun 55 | OI(): arrow.typeclasses.Monoid = OI 56 | 57 | override fun MF(): arrow.typeclasses.Monad = MF 58 | } 59 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/extensions/schedule/semigroupK/ScheduleSemigroupK.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.extensions.schedule.semigroupK 2 | 3 | import arrow.Kind 4 | import arrow.fx.ForSchedule 5 | import arrow.fx.IODeprecation 6 | import arrow.fx.Schedule 7 | import arrow.fx.Schedule.Companion 8 | import arrow.fx.extensions.ScheduleSemigroupK 9 | import arrow.typeclasses.Semigroup 10 | import kotlin.Any 11 | import kotlin.Deprecated 12 | import kotlin.PublishedApi 13 | import kotlin.Suppress 14 | import kotlin.jvm.JvmName 15 | 16 | /** 17 | * cached extension 18 | */ 19 | @PublishedApi() 20 | internal val semigroupK_singleton: ScheduleSemigroupK = object : 21 | ScheduleSemigroupK {} 22 | 23 | @JvmName("combineK") 24 | @Suppress( 25 | "UNCHECKED_CAST", 26 | "USELESS_CAST", 27 | "EXTENSION_SHADOWED_BY_MEMBER", 28 | "UNUSED_PARAMETER" 29 | ) 30 | @Deprecated(IODeprecation) 31 | fun Kind, Input>, 32 | A>.combineK(arg1: Kind, Input>, A>): Schedule = 33 | arrow.fx.Schedule.semigroupK().run { 34 | this@combineK.combineK(arg1) as arrow.fx.Schedule 35 | } 36 | 37 | @JvmName("algebra") 38 | @Suppress( 39 | "UNCHECKED_CAST", 40 | "USELESS_CAST", 41 | "EXTENSION_SHADOWED_BY_MEMBER", 42 | "UNUSED_PARAMETER" 43 | ) 44 | @Deprecated(IODeprecation) 45 | fun algebra(): Semigroup, Input>, A>> = 46 | arrow.fx.Schedule 47 | .semigroupK() 48 | .algebra() as 49 | arrow.typeclasses.Semigroup, Input>, 50 | A>> 51 | 52 | @Suppress( 53 | "UNCHECKED_CAST", 54 | "NOTHING_TO_INLINE" 55 | ) 56 | @Deprecated(IODeprecation) 57 | inline fun Companion.semigroupK(): ScheduleSemigroupK = semigroupK_singleton as 58 | arrow.fx.extensions.ScheduleSemigroupK 59 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/IOFrame.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx 2 | 3 | import arrow.core.Either 4 | import arrow.fx.IO.Pure 5 | 6 | /** 7 | * An [IOFrame] knows how to [recover] from a [Throwable] and how to map a value [A] to [R]. 8 | * 9 | * Internal to `IO`'s implementations, used to specify 10 | * error handlers in their respective `Bind` internal states. 11 | * 12 | * To use an [IOFrame] you must use [IO.Bind] instead of `flatMap` or the [IOFrame] 13 | * is **not guaranteed** to execute. 14 | * 15 | * It's used to implement [attempt], [handleErrorWith] and [arrow.fx.internal.IOBracket] 16 | */ 17 | internal interface IOFrame : (A) -> R { 18 | override operator fun invoke(a: A): R 19 | 20 | fun recover(e: Throwable): R 21 | 22 | companion object { 23 | 24 | internal class Redeem(val fe: (Throwable) -> B, val fb: (A) -> B) : IOFrame> { 25 | override fun invoke(a: A): IO = Pure(fb(a)) 26 | override fun recover(e: Throwable): IO = Pure(fe(e)) 27 | } 28 | 29 | internal class RedeemWith(val fe: (Throwable) -> IOOf, val fb: (A) -> IOOf) : IOFrame> { 30 | override fun invoke(a: A): IO = fb(a).fix() 31 | override fun recover(e: Throwable): IO = fe(e).fix() 32 | } 33 | 34 | internal class ErrorHandler(val fe: (Throwable) -> IOOf) : IOFrame> { 35 | override fun invoke(a: A): IO = Pure(a) 36 | override fun recover(e: Throwable): IO = fe(e).fix() 37 | } 38 | 39 | @Suppress("UNCHECKED_CAST") 40 | fun attempt(): (A) -> IO> = AttemptIO as (A) -> IO> 41 | 42 | private object AttemptIO : IOFrame>> { 43 | override operator fun invoke(a: Any?): IO> = Pure(Either.Right(a)) 44 | override fun recover(e: Throwable): IO> = Pure(Either.Left(e)) 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /arrow-docs/src/main/kotlin/AQLHelper.kt: -------------------------------------------------------------------------------- 1 | package arrow.aql 2 | 3 | import arrow.core.Eval 4 | import arrow.core.Option 5 | import arrow.extension 6 | import arrow.typeclasses.FunctorFilter 7 | import arrow.typeclasses.Foldable 8 | import arrow.typeclasses.Functor 9 | import arrow.undocumented 10 | 11 | class ForBox private constructor() { 12 | companion object 13 | } 14 | typealias BoxOf = arrow.Kind 15 | 16 | @Suppress("UNCHECKED_CAST", "NOTHING_TO_INLINE") 17 | inline fun BoxOf.fix(): Box = 18 | this as Box 19 | 20 | // @higherkind 21 | sealed class Box : BoxOf { 22 | 23 | object Empty : Box() 24 | 25 | data class Full(val value: A) : Box() 26 | 27 | companion object { 28 | fun empty(): Box = Empty 29 | } 30 | } 31 | 32 | @extension 33 | @undocumented 34 | interface BoxFunctor : Functor { 35 | override fun BoxOf.map(f: (A) -> B): Box = 36 | when (val box = fix()) { 37 | Box.Empty -> Box.empty() 38 | is Box.Full -> Box.Full(f(box.value)) 39 | } 40 | } 41 | 42 | @extension 43 | interface BoxFunctorFilter : FunctorFilter, BoxFunctor { 44 | override fun BoxOf.filterMap(f: (A) -> Option): Box = 45 | when (val box = fix()) { 46 | Box.Empty -> Box.empty() 47 | is Box.Full -> f(box.value).fold( 48 | { Box.empty() }, 49 | { Box.Full(it) } 50 | ) 51 | } 52 | } 53 | 54 | @extension 55 | interface BoxFoldable : Foldable { 56 | override fun BoxOf.foldLeft(b: B, f: (B, A) -> B): B = 57 | fix().let { 58 | when (it) { 59 | is Box.Full -> f(b, it.value) 60 | Box.Empty -> b 61 | } 62 | } 63 | 64 | override fun BoxOf.foldRight(lb: Eval, f: (A, Eval) -> Eval): Eval = 65 | fix().let { 66 | when (it) { 67 | is Box.Full -> f(it.value, lb) 68 | Box.Empty -> lb 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/extensions/schedule/category/ScheduleCategory.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.extensions.schedule.category 2 | 3 | import arrow.Kind 4 | import arrow.fx.ForSchedule 5 | import arrow.fx.IODeprecation 6 | import arrow.fx.Schedule 7 | import arrow.fx.Schedule.Companion 8 | import arrow.fx.extensions.ScheduleCategory 9 | import arrow.typeclasses.Monad 10 | import kotlin.Deprecated 11 | import kotlin.Suppress 12 | import kotlin.jvm.JvmName 13 | 14 | @JvmName("compose") 15 | @Suppress( 16 | "UNCHECKED_CAST", 17 | "USELESS_CAST", 18 | "EXTENSION_SHADOWED_BY_MEMBER", 19 | "UNUSED_PARAMETER" 20 | ) 21 | @Deprecated(IODeprecation) 22 | fun Kind, B>, C>.compose( 23 | MM: Monad, 24 | arg1: Kind, A>, B> 25 | ): Schedule = 26 | arrow.fx.Schedule.category(MM).run { 27 | this@compose.compose(arg1) as arrow.fx.Schedule 28 | } 29 | 30 | @JvmName("andThen") 31 | @Suppress( 32 | "UNCHECKED_CAST", 33 | "USELESS_CAST", 34 | "EXTENSION_SHADOWED_BY_MEMBER", 35 | "UNUSED_PARAMETER" 36 | ) 37 | @Deprecated(IODeprecation) 38 | fun Kind, A>, B>.andThen( 39 | MM: Monad, 40 | arg1: Kind, B>, C> 41 | ): Schedule = 42 | arrow.fx.Schedule.category(MM).run { 43 | this@andThen.andThen(arg1) as arrow.fx.Schedule 44 | } 45 | 46 | @JvmName("id") 47 | @Suppress( 48 | "UNCHECKED_CAST", 49 | "USELESS_CAST", 50 | "EXTENSION_SHADOWED_BY_MEMBER", 51 | "UNUSED_PARAMETER" 52 | ) 53 | @Deprecated(IODeprecation) 54 | fun id(MM: Monad): Schedule = arrow.fx.Schedule 55 | .category(MM) 56 | .id() as arrow.fx.Schedule 57 | 58 | @Suppress( 59 | "UNCHECKED_CAST", 60 | "NOTHING_TO_INLINE" 61 | ) 62 | @Deprecated(IODeprecation) 63 | inline fun Companion.category(MM: Monad): ScheduleCategory = object : 64 | arrow.fx.extensions.ScheduleCategory { override fun MM(): arrow.typeclasses.Monad = MM } 65 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/typeclasses/MonadDefer.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.typeclasses 2 | 3 | import arrow.Kind 4 | import arrow.core.Either 5 | import arrow.fx.IODeprecation 6 | import arrow.fx.Ref 7 | import arrow.typeclasses.MonadThrow 8 | 9 | /** 10 | * The context required to defer evaluating a safe computation. 11 | **/ 12 | @Deprecated(IODeprecation) 13 | interface MonadDefer : MonadThrow, Bracket { 14 | 15 | fun defer(fa: () -> Kind): Kind 16 | 17 | fun later(f: () -> A): Kind = 18 | defer { 19 | try { 20 | just(f()) 21 | } catch (t: Throwable) { 22 | t.raiseNonFatal() 23 | } 24 | } 25 | 26 | fun later(fa: Kind): Kind = defer { fa } 27 | 28 | fun lazy(): Kind = later { } 29 | 30 | fun laterOrRaise(f: () -> Either): Kind = 31 | defer { f().fold({ raiseError(it) }, { just(it) }) } 32 | 33 | /** 34 | * Create a [Ref] a pure atomic reference to safely manage mutable state. 35 | * It's a pure version of [java.util.concurrent.atomic.AtomicReference] that works in context [F]. 36 | * 37 | * It's always initialized to a value, and allows for concurrent updates. 38 | * 39 | * ```kotlin:ank:playground 40 | * import arrow.Kind 41 | * import arrow.core.Tuple2 42 | * import arrow.fx.* 43 | * import arrow.fx.extensions.io.monadDefer.monadDefer 44 | * import arrow.fx.typeclasses.MonadDefer 45 | * 46 | * fun main(args: Array) { 47 | * fun MonadDefer.refExample(): Kind> = 48 | * //sampleStart 49 | * fx.monad { 50 | * val ref = !Ref(1) 51 | * val initial = !ref.getAndUpdate(Int::inc) 52 | * val updated = !ref.get() 53 | * Tuple2(initial, updated) 54 | * } 55 | * 56 | * //sampleEnd 57 | * IO.monadDefer().refExample() 58 | * .fix().unsafeRunSync().let(::println) 59 | * } 60 | * ``` 61 | */ 62 | fun Ref(a: A): Kind> = Ref(this, a) 63 | } 64 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/IODispatchers.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx 2 | 3 | import arrow.fx.internal.AtomicIntW 4 | import arrow.undocumented 5 | import java.util.concurrent.ExecutorService 6 | import java.util.concurrent.Executors 7 | import java.util.concurrent.ForkJoinPool 8 | import kotlin.coroutines.AbstractCoroutineContextElement 9 | import kotlin.coroutines.Continuation 10 | import kotlin.coroutines.ContinuationInterceptor 11 | import kotlin.coroutines.CoroutineContext 12 | 13 | @undocumented 14 | // FIXME use expected and actual for multiplatform 15 | @Deprecated(IODeprecation) 16 | object IODispatchers { 17 | // FIXME use ForkJoinPool.commonPool() in Java 8 18 | val CommonPool: CoroutineContext = ForkJoinPool().asCoroutineContext() 19 | 20 | private val ioCtr = AtomicIntW(0) 21 | val IOPool = Executors.newCachedThreadPool { r -> 22 | Thread(r).apply { 23 | name = "io-arrow-kt-worker-${ioCtr.getAndIncrement()}" 24 | isDaemon = true 25 | } 26 | }.asCoroutineContext() 27 | } 28 | 29 | @Deprecated(IODeprecation, ReplaceWith("Resource.fromExecutor { this }", "arrow.fx.coroutines")) 30 | fun ExecutorService.asCoroutineContext(): CoroutineContext = 31 | ExecutorServiceContext(this) 32 | 33 | private class ExecutorServiceContext(val pool: ExecutorService) : AbstractCoroutineContextElement(ContinuationInterceptor), ContinuationInterceptor { 34 | override fun interceptContinuation(continuation: Continuation): Continuation = 35 | ExecutorServiceContinuation( 36 | pool, 37 | continuation.context.fold(continuation) { cont, element -> 38 | if (element != this@ExecutorServiceContext && element is ContinuationInterceptor) 39 | element.interceptContinuation(cont) else cont 40 | } 41 | ) 42 | } 43 | 44 | private class ExecutorServiceContinuation( 45 | val pool: ExecutorService, 46 | val cont: Continuation 47 | ) : Continuation { 48 | override val context: CoroutineContext = cont.context 49 | 50 | override fun resumeWith(result: Result) { 51 | pool.execute { cont.resumeWith(result) } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /arrow-fx-stm/src/test/kotlin/arrow/fx/stm/TMapTest.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.stm 2 | 3 | import arrow.fx.coroutines.ArrowFxSpec 4 | import io.kotest.matchers.shouldBe 5 | import io.kotest.property.Arb 6 | import io.kotest.property.arbitrary.int 7 | import io.kotest.property.arbitrary.list 8 | import io.kotest.property.arbitrary.pair 9 | 10 | class TMapTest : ArrowFxSpec( 11 | spec = { 12 | "insert values" { 13 | checkAll(Arb.int(), Arb.int()) { k, v -> 14 | val map = TMap.new() 15 | atomically { map.insert(k, v) } 16 | atomically { map.lookup(k) } shouldBe v 17 | } 18 | } 19 | "insert multiple values" { 20 | checkAll(Arb.list(Arb.pair(Arb.int(), Arb.int()))) { pairs -> 21 | val map = TMap.new() 22 | atomically { 23 | for ((k, v) in pairs) map.insert(k, v) 24 | } 25 | atomically { 26 | for ((k, v) in pairs) map.lookup(k) shouldBe v 27 | } 28 | } 29 | } 30 | "insert multiple colliding values" { 31 | checkAll(Arb.list(Arb.pair(Arb.int(), Arb.int()))) { pairs -> 32 | val map = TMap.new { 0 } // hash function that always returns 0 33 | atomically { 34 | for ((k, v) in pairs) map.insert(k, v) 35 | } 36 | atomically { 37 | for ((k, v) in pairs) map.lookup(k) shouldBe v 38 | } 39 | } 40 | } 41 | "insert and remove" { 42 | checkAll(Arb.int(), Arb.int()) { k, v -> 43 | val map = TMap.new() 44 | atomically { map.insert(k, v) } 45 | atomically { map.lookup(k) } shouldBe v 46 | atomically { map.remove(k) } 47 | atomically { map.lookup(k) } shouldBe null 48 | } 49 | } 50 | "update" { 51 | checkAll(Arb.int(), Arb.int(), Arb.int()) { k, v, g -> 52 | val map = TMap.new() 53 | atomically { map.insert(k, v) } 54 | atomically { map.lookup(k) } shouldBe v 55 | atomically { map.update(k) { v + g } } 56 | atomically { map.lookup(k) } shouldBe v + g 57 | } 58 | } 59 | } 60 | ) 61 | -------------------------------------------------------------------------------- /arrow-fx/src/main/kotlin/arrow/fx/extensions/io/monadError/IOMonadError.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.extensions.io.monadError 2 | 3 | import arrow.Kind 4 | import arrow.core.Either 5 | import arrow.fx.ForIO 6 | import arrow.fx.IO 7 | import arrow.fx.IO.Companion 8 | import arrow.fx.IODeprecation 9 | import arrow.fx.extensions.IOMonadError 10 | import kotlin.Boolean 11 | import kotlin.Deprecated 12 | import kotlin.Function0 13 | import kotlin.Function1 14 | import kotlin.PublishedApi 15 | import kotlin.Suppress 16 | import kotlin.Throwable 17 | import kotlin.jvm.JvmName 18 | 19 | /** 20 | * cached extension 21 | */ 22 | @PublishedApi() 23 | internal val monadError_singleton: IOMonadError = object : arrow.fx.extensions.IOMonadError {} 24 | 25 | @JvmName("ensure") 26 | @Suppress( 27 | "UNCHECKED_CAST", 28 | "USELESS_CAST", 29 | "EXTENSION_SHADOWED_BY_MEMBER", 30 | "UNUSED_PARAMETER" 31 | ) 32 | @Deprecated(IODeprecation) 33 | fun Kind.ensure(arg1: Function0, arg2: Function1): IO = 34 | arrow.fx.IO.monadError().run { 35 | this@ensure.ensure(arg1, arg2) as arrow.fx.IO 36 | } 37 | 38 | @JvmName("redeemWith") 39 | @Suppress( 40 | "UNCHECKED_CAST", 41 | "USELESS_CAST", 42 | "EXTENSION_SHADOWED_BY_MEMBER", 43 | "UNUSED_PARAMETER" 44 | ) 45 | @Deprecated(IODeprecation) 46 | fun Kind.redeemWith( 47 | arg1: Function1>, 48 | arg2: Function1> 50 | ): IO = arrow.fx.IO.monadError().run { 51 | this@redeemWith.redeemWith(arg1, arg2) as arrow.fx.IO 52 | } 53 | 54 | @JvmName("rethrow") 55 | @Suppress( 56 | "UNCHECKED_CAST", 57 | "USELESS_CAST", 58 | "EXTENSION_SHADOWED_BY_MEMBER", 59 | "UNUSED_PARAMETER" 60 | ) 61 | @Deprecated(IODeprecation) 62 | fun Kind>.rethrow(): IO = arrow.fx.IO.monadError().run { 63 | this@rethrow.rethrow() as arrow.fx.IO 64 | } 65 | 66 | @Suppress( 67 | "UNCHECKED_CAST", 68 | "NOTHING_TO_INLINE" 69 | ) 70 | @Deprecated(IODeprecation) 71 | inline fun Companion.monadError(): IOMonadError = monadError_singleton 72 | -------------------------------------------------------------------------------- /arrow-fx-coroutines/src/main/kotlin/arrow/fx/coroutines/stream/Pipe.kt: -------------------------------------------------------------------------------- 1 | package arrow.fx.coroutines.stream 2 | 3 | /** 4 | * A stream transformation can be represented as a function from stream to stream. 5 | * This means that `Pipe` is also an alias for `fun Stream.name(): Stream`. 6 | * 7 | * Pipes are typically applied with the `through` operation on `Stream`. 8 | * 9 | * This is useful when you want to expose a `Stream` transformation from a data type. 10 | * This can not conveniently be done with extension functions. 11 | * 12 | * i.e. [arrow.fx.coroutines.stream.concurrent.Queue.dequeueBatch] 13 | */ 14 | @Deprecated("Pipe is deprecated as part of Stream deprecation.") 15 | typealias Pipe = (Stream) -> Stream 16 | 17 | @Deprecated("Pipe is deprecated as part of Stream deprecation.") 18 | fun Pipe(pipe: (Stream) -> Stream): Pipe = pipe 19 | 20 | /** Transforms the left input of the given `Pipe2` using a `Pipe`. */ 21 | @Deprecated("Pipe is deprecated as part of Stream deprecation.") 22 | fun Pipe.attachLeft(p: Pipe2): Pipe2 = 23 | { l, r -> p(this(l), r) } 24 | 25 | /** Transforms the right input of the given `Pipe2` using a `Pipe`. */ 26 | @Deprecated("Pipe is deprecated as part of Stream deprecation.") 27 | fun Pipe.attachRight(p: Pipe2): Pipe2 = 28 | { l, r -> p(l, this(r)) } 29 | 30 | /** 31 | * A stream transformation that combines two streams in to a single stream, 32 | * represented as a function from two streams to a single stream. 33 | * 34 | * Since we cannot define extension functions with multiple subscribers, 35 | * `Pipe2` is not an alias for extension functions but allows more powerful transformations. 36 | * 37 | * `Pipe2`s are typically applied with the `through` operation on `Stream`. 38 | */ 39 | @Deprecated("Pipe is deprecated as part of Stream deprecation.") 40 | typealias Pipe2 = (Stream, Stream) -> Stream 41 | 42 | @Deprecated("Pipe is deprecated as part of Stream deprecation.") 43 | fun Pipe2(pipe: (Stream, Stream) -> Stream): Pipe2 = pipe 44 | --------------------------------------------------------------------------------