-
-
Notifications
You must be signed in to change notification settings - Fork 244
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
1,099 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
94 changes: 94 additions & 0 deletions
94
monix-types/shared/src/main/scala/monix/types/FFoldable.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
/* | ||
* Copyright (c) 2014-2016 by its authors. Some rights reserved. | ||
* See the project homepage at: https://monix.io | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package monix.types | ||
|
||
import algebra.Monoid | ||
import simulacrum.typeclass | ||
import scala.language.{higherKinds, implicitConversions} | ||
|
||
/** Data structures that can be folded to a summary value, | ||
* possibly lazily or asynchronously. | ||
* | ||
* The main operation is `foldLeftF` that folds `fa` | ||
* from left to right, or from first to last. Beyond this it | ||
* provides many other useful methods related to | ||
* folding over `F[A]` values. | ||
* | ||
* Note that a corresponding `foldRight` is not provided, | ||
* because that would be incompatible with large or infinite | ||
* streams. | ||
* | ||
* See: [[http://www.cs.nott.ac.uk/~pszgmh/fold.pdf A tutorial on the universality and expressiveness of fold]]. | ||
*/ | ||
|
||
@typeclass trait FFoldable[F[_]] { | ||
/** Left associative asynchronous fold on 'F' using the function 'f'. */ | ||
def foldLeftF[A, S](fa: F[A], seed: S)(f: (S, A) => S): F[S] | ||
|
||
/** Given a sequences, produces a new sequence that will expose the | ||
* count of the source. | ||
*/ | ||
def countF[A](fa: F[A]): F[Long] = | ||
foldLeftF(fa, 0L)((acc,_) => acc + 1) | ||
|
||
/** Check whether at least one element satisfies the predicate. | ||
* | ||
* If there are no elements, the result is `false`. | ||
*/ | ||
def existsF[A](fa: F[A])(p: A => Boolean): F[Boolean] = | ||
foldLeftF(fa, false) { (acc, elem) => acc || p(elem) } | ||
|
||
/** Find the first element matching the predicate, if one exists. */ | ||
def findOptF[A](fa: F[A])(p: A => Boolean): F[Option[A]] = | ||
foldLeftF(fa, Option.empty[A]) { | ||
(acc, elem) => acc match { | ||
case None => if (p(elem)) Some(elem) else None | ||
case ref @ Some(_) => ref | ||
} | ||
} | ||
|
||
/** Folds a `Monoid`. */ | ||
def foldF[A](fa: F[A])(implicit A: Monoid[A]): F[A] = | ||
foldLeftF(fa, A.empty)(A.combine) | ||
|
||
/** Fold implemented by mapping `A` values into `B` and then | ||
* combining them using the given `Monoid[B]` instance. | ||
*/ | ||
def foldMapF[A, B](fa: F[A])(f: A => B)(implicit B: Monoid[B]): F[B] = | ||
foldLeftF(fa, B.empty)((b, a) => B.combine(b, f(a))) | ||
|
||
/** Check whether all elements satisfies the predicate. | ||
* | ||
* If at least one element doesn't satisfy the predicate, | ||
* the result is `false`. | ||
*/ | ||
def forAllF[A](fa: F[A])(p: A => Boolean): F[Boolean] = | ||
foldLeftF(fa, true) { (acc, elem) => acc && p(elem) } | ||
|
||
/** Checks if the source sequence is empty. */ | ||
def isEmptyF[A](fa: F[A]): F[Boolean] = | ||
foldLeftF(fa, true)((_,_) => false) | ||
|
||
/** Checks if the source sequence is non-empty. */ | ||
def nonEmptyF[A](fa: F[A]): F[Boolean] = | ||
foldLeftF(fa, false)((_,_) => true) | ||
|
||
/** Given a sequence of numbers, calculates a sum. */ | ||
def sumF[A](fa: F[A])(implicit A: Numeric[A]): F[A] = | ||
foldLeftF(fa, A.zero)(A.plus) | ||
} |
55 changes: 55 additions & 0 deletions
55
monix-types/shared/src/main/scala/monix/types/MonadCons.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/* | ||
* Copyright (c) 2014-2016 by its authors. Some rights reserved. | ||
* See the project homepage at: https://monix.io | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package monix.types | ||
|
||
import simulacrum._ | ||
import scala.language.{higherKinds, implicitConversions} | ||
|
||
/** Type-class for monadic data-structures that can expose | ||
* multiple `A` elements. | ||
*/ | ||
@typeclass trait MonadCons[F[_]] extends Monad[F] { | ||
/** Builds an instance by joining a head and a lazy tail. */ | ||
def cons[A](head: A, tail: => F[A]): F[A] | ||
|
||
/** Alias for `flatMap`. */ | ||
def concatMap[A,B](fa: F[A])(f: A => F[B]): F[B] | ||
|
||
/** Alias for `flatten`. */ | ||
def concat[A](ffa: F[F[A]]): F[A] = | ||
concatMap(ffa)(fa => fa) | ||
|
||
/** Concatenates the source with `other`. */ | ||
@op("++") def followWith[A](fa: F[A])(that: => F[A]): F[A] = | ||
flatMap(cons(fa, pure(that)))(fa => fa) | ||
/** Appends the given `elem` at the end. */ | ||
@op(":+") def endWithElem[A](fa: F[A])(elem: A): F[A] = | ||
followWith(fa)(pure(elem)) | ||
/** Prepends the given `elem` at the start. */ | ||
@op("+:") def startWithElem[A](fa: F[A])(elem: A): F[A] = | ||
followWith(pure(elem))(fa) | ||
|
||
/** Repeats the source, continuously. */ | ||
def repeat[A](fa: F[A]): F[A] = | ||
followWith(fa)(repeat(fa)) | ||
|
||
override def flatten[A](ffa: F[F[A]]): F[A] = | ||
concat(ffa) | ||
override def flatMap[A, B](fa: F[A])(f: (A) => F[B]): F[B] = | ||
concatMap(fa)(f) | ||
} |
50 changes: 50 additions & 0 deletions
50
monix-types/shared/src/main/scala/monix/types/MonadConsError.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
* Copyright (c) 2014-2016 by its authors. Some rights reserved. | ||
* See the project homepage at: https://monix.io | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package monix.types | ||
|
||
import scala.language.{higherKinds, implicitConversions} | ||
|
||
/** Type-class for monadic data-structures that can expose | ||
* multiple `A` elements. | ||
*/ | ||
trait MonadConsError[F[_],E] extends MonadCons[F] with Recoverable[F,E] { | ||
/** A variant of [[concatMap]] that delays any triggered errors | ||
* for as long as possible. | ||
* | ||
* Typically this means delaying any errors until the source | ||
* and any child produced by the given function are complete. | ||
* Since this can involve delaying multiple errors, it is | ||
* recommended for the final error to be a composite. | ||
*/ | ||
def concatMapDelayError[A,B](fa: F[A])(f: A => F[B]): F[B] | ||
|
||
/** A variant of [[concat]] that delays any triggered errors | ||
* for as long as possible. | ||
* | ||
* Typically this means delaying any errors until the source | ||
* and any child produced by it are complete. Since this can | ||
* involve delaying multiple errors, it is recommended for | ||
* the final error to be a composite. | ||
*/ | ||
def concatDelayError[A](ffa: F[F[A]]): F[A] = | ||
concatMapDelayError(ffa)(identity) | ||
|
||
/** Mirrors the source, but ends it in error. */ | ||
def endWithError[A](fa: F[A], error: E): F[A] = | ||
followWith(fa)(raiseError(error)) | ||
} |
55 changes: 55 additions & 0 deletions
55
monix-types/shared/src/main/scala/monix/types/Nondeterminism.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/* | ||
* Copyright (c) 2014-2016 by its authors. Some rights reserved. | ||
* See the project homepage at: https://monix.io | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package monix.types | ||
|
||
import simulacrum.typeclass | ||
import scala.concurrent.duration.FiniteDuration | ||
import scala.language.{higherKinds, implicitConversions} | ||
|
||
@typeclass trait Nondeterminism[F[_]] { | ||
/** Given a list of non-deterministic structures, mirrors the | ||
* first that manages to emit an element or that completes and | ||
* ignore or cancel the rest. | ||
*/ | ||
def firstStartedOf[A](seq: Seq[F[A]]): F[A] | ||
|
||
/** Delays the execution of the instance and consequently the execution of | ||
* any side-effects, by the specified `timespan`. | ||
*/ | ||
def delayExecution[A](fa: F[A], timespan: FiniteDuration): F[A] | ||
|
||
/** Delays the execution of the instance and consequently the execution of | ||
* any side-effects, until the given `trigger` emits an element or completes. | ||
*/ | ||
def delayExecutionWith[A,B](fa: F[A], trigger: F[B]): F[A] | ||
|
||
/** Executes the source immediately, but delays the signaling by | ||
* the specified `timespan`. In case `F` is a sequence, | ||
* then the delay will be applied to each element, but not | ||
* to completion or the signaling of an error. | ||
*/ | ||
def delayResult[A](fa: F[A], timespan: FiniteDuration): F[A] | ||
|
||
/** Executes the source immediately, but delays the signaling | ||
* until the specified `selector` emits an element or completes. | ||
* In case `F` is a sequence, then the delay will be applied | ||
* to each element, but not to completion or the | ||
* signaling of an error. | ||
*/ | ||
def delayResultBySelector[A,B](fa: F[A])(selector: A => F[B]): F[A] | ||
} |
Oops, something went wrong.