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.scala17
1 files changed, 9 insertions, 8 deletions
diff --git a/core/shared/src/main/scala/interface.scala b/core/shared/src/main/scala/interface.scala
index 193a6f9..a4be9ab 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
*
@@ -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)
+ }
}