Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Optional an IterableOnce #1418

Merged
merged 12 commits into from
Nov 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package zio.prelude.data

import zio.Scope
import zio.prelude.ZIOBaseSpec
import zio.test.{Spec, TestEnvironment, assertTrue}

object OptionalSpec extends ZIOBaseSpec {

override def spec: Spec[TestEnvironment with Scope, Any] =
suite("Optional")(
test("is an IterableOnce") {
def get(a: Int): Optional[Long] = Optional.Present(a.toLong)
val list: List[Int] = List(1, 2, 3)
val result: List[Long] = list.flatMap(get)

assertTrue(result == List(1L, 2L, 3L))
}
)

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package zio.prelude

/**
* Needed because Scala 2.12 doesn't have `IterableOnce`
*/
private[prelude] trait IterableOnceCompat[+A] {

/**
* Copied from `IterableOnce#iterator`
*/
def iterator: Iterator[A]

/**
* Adapted from `IterableOnce#knownSize`
*/
def knownSize: Int

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package zio.prelude

/**
* Needed because Scala 2.12 doesn't have `IterableOnce`
*
* TODO: Remove when support for Scala 2.12 is dropped
*/
private[prelude] trait IterableOnceCompat[+A] extends IterableOnce[A]
11 changes: 9 additions & 2 deletions core/shared/src/main/scala/zio/prelude/data/Optional.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package zio.prelude.data

import zio.Chunk
import zio.prelude.IterableOnceCompat

import scala.language.implicitConversions

Expand All @@ -13,7 +14,7 @@ import scala.language.implicitConversions
* The only difference between this type and [[scala.Option]] is that there is an implicit
* conversion defined from `A`` to `Optional[A]`, and from `Option[A]`` to `Optional[A]`.
*/
sealed trait Optional[+A] { self =>
sealed trait Optional[+A] extends IterableOnceCompat[A] { self =>
val isEmpty: Boolean
val isDefined: Boolean
val nonEmpty: Boolean
Expand Down Expand Up @@ -122,7 +123,7 @@ sealed trait Optional[+A] { self =>
final def orElse[B >: A](alternative: => Optional[B]): Optional[B] =
if (isEmpty) alternative else this

final def iterator: Iterator[A] =
override final def iterator: Iterator[A] =
self match {
case Optional.Present(get) => Iterator.single(get)
case Optional.Absent => Iterator.empty
Expand All @@ -145,6 +146,12 @@ sealed trait Optional[+A] { self =>
case Optional.Present(get) => Vector(get)
case Optional.Absent => Vector.empty
}

/**
* Copied from `Option.knownSize`
*/
override final def knownSize: Int = if (isEmpty) 0 else 1

}

object Optional {
Expand Down