Skip to content

Instantly share code, notes, and snippets.

@sir-wabbit
Created August 30, 2019 16:19
Show Gist options
  • Save sir-wabbit/eaeb5a9f2ff289ad72bcacc6130b7f0a to your computer and use it in GitHub Desktop.
Save sir-wabbit/eaeb5a9f2ff289ad72bcacc6130b7f0a to your computer and use it in GitHub Desktop.
import scala.util.control.NonFatal
type && [F[_], G[_]] = [x] =>> F[x] & G[x]
trait CombinatorErrors[E] {
def tupleLeft(e: E): E
def tupleRight(e: E): E
def tupleBoth(e1: E, e2: E): E
}
trait Reader[-C[_], +A] { A =>
def read[E](s: String)(implicit E: C[E]): Either[E, A]
}
object Reader {
given ReaderOps {
def (A: Reader[C, A]) zip[C[_], A, K[_], B](B: Reader[K, B]): Reader[C && K && CombinatorErrors, (A, B)] =
new Reader[C && K && CombinatorErrors, (A, B)] {
def read[E](s: String)(implicit ev: (C && K && CombinatorErrors)[E]): Either[E, (A, B)] =
(A.read(s), B.read(s)) match {
case (Left(e1), Left(e2)) => Left(ev.tupleBoth(e1, e2))
case (Left(e1), Right(_)) => Left(ev.tupleLeft(e1))
case (Right(_), Left(e2)) => Left(ev.tupleRight(e2))
case (Right(a), Right(b)) => Right((a, b))
}
}
}
}
trait IntErrors[E] {
def invalidInt(s: String): E
}
given intReader as Reader[IntErrors, Int] {
def read[E](s: String)(implicit E: IntErrors[E]): Either[E, Int] =
try Right(s.toInt) catch {
case NonFatal(e) => Left(E.invalidInt(s))
}
}
trait LongErrors[E] {
def invalidLong(s: String): E
}
given longReader as Reader[LongErrors, Long] {
def read[E](s: String)(implicit E: LongErrors[E]): Either[E, Long] =
try Right(s.toLong) catch {
case NonFatal(e) => Left(E.invalidLong(s))
}
}
trait DoubleErrors[E] {
def invalidDouble(s: String): E
}
given doubleReader as Reader[DoubleErrors, Double] {
def read[E](s: String)(implicit E: DoubleErrors[E]): Either[E, Double] =
try Right(s.toDouble) catch {
case NonFatal(e) => Left(E.invalidDouble(s))
}
}
val test: Reader[IntErrors && LongErrors && DoubleErrors && CombinatorErrors, ((Int, Long), Double)] =
(intReader zip longReader) zip doubleReader
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment