aboutsummaryrefslogtreecommitdiff
path: root/core/shared/src/main/scala/interface.scala
diff options
context:
space:
mode:
Diffstat (limited to 'core/shared/src/main/scala/interface.scala')
-rw-r--r--core/shared/src/main/scala/interface.scala19
1 files changed, 10 insertions, 9 deletions
diff --git a/core/shared/src/main/scala/interface.scala b/core/shared/src/main/scala/interface.scala
index 193a6f9..a82a54c 100644
--- a/core/shared/src/main/scala/interface.scala
+++ b/core/shared/src/main/scala/interface.scala
@@ -1,6 +1,7 @@
package magnolia
import language.higherKinds
+import scala.annotation.tailrec
/** represents a subtype of a sealed trait
*
@@ -128,7 +129,7 @@ abstract class CaseClass[Typeclass[_], Type] private[magnolia] (
*
* For efficiency, this sequence is implemented by an `Array`, but upcast to a
* [[scala.collection.Seq]] to hide the mutable collection API. */
- def parameters: Seq[Param[Typeclass, Type]] = parametersArray
+ final def parameters: Seq[Param[Typeclass, Type]] = parametersArray
}
/** represents a sealed trait and the context required to construct a new typeclass instance
@@ -157,12 +158,12 @@ final class SealedTrait[Typeclass[_], Type](val typeName: String,
* matches
* @return the result of applying the `handle` lambda to subtype of the sealed trait which
* matches the parameter `value` */
- def dispatch[Return](value: Type)(handle: Subtype[Typeclass, Type] => Return): Return =
- subtypes
- .map { sub =>
- sub.cast.andThen { v =>
- handle(sub)
- }
- }
- .reduce(_ orElse _)(value)
+ def dispatch[Return](value: Type)(handle: Subtype[Typeclass, Type] => Return): Return = {
+ @tailrec def rec(ix: Int): Return =
+ if (ix < subtypesArray.length) {
+ val sub = subtypesArray(ix)
+ if (sub.cast.isDefinedAt(value)) handle(sub) else rec(ix + 1)
+ } else throw new IllegalArgumentException(s"The given value `$value` is not a sub type of `$typeName`")
+ rec(0)
+ }
}