Skip to content

Instantly share code, notes, and snippets.

@kitlangton
Created August 6, 2021 19:30
Show Gist options
  • Save kitlangton/1d5691e6e273ffb143046debe6af596a to your computer and use it in GitHub Desktop.
Save kitlangton/1d5691e6e273ffb143046debe6af596a to your computer and use it in GitHub Desktop.
package zio
object PathDependentTypes {
val zio1: ZIO[Any, Nothing, Int] = ZIO.succeed(1)
val zio2: ZIO[Any, Nothing, Int] = ZIO.succeed(2)
val zio3: ZIO[Any, Nothing, Int] = ZIO.succeed(3)
val zio4 = zio1 <*> zio2 <*> zio3 <*> zio1 <*> zio2
def zip[R, E, A, B](left: ZIO[R, E, A], right: ZIO[R, E, B]): ZIO[R, E, (A, B)] =
???
object Box1 {
type A = Nothing
}
trait Box { self =>
type A
def value: A
def printContents(): Unit =
println(value)
def tupleBox(that: Box): Box.WithContents[(self.A, that.A)] =
new Box {
type A = (self.A, that.A)
val value = (self.value, that.value)
}
}
object Box {
type WithContents[A0] = Box { type A = A0 }
def apply[A0](a: A0): Box.WithContents[A0] =
new Box {
type A = A0
val value = a
}
}
val box = Box(1)
val box2 = Box("Adam")
val x = box.value + box.value
val boxes = List(box, box2)
val tupleBox = box.tupleBox(box2)
val tupleBox2 = tupleBox
val tupleBox3 = tupleBox2
val a = tupleBox3.value
tupleBox.printContents()
trait Schedule[-Env, -In, +Out] {
type State
def initial: State
def step(in: In, state: State): (State, Out, Decision)
}
object Schedule {
type WithState[-Env, -In, +Out, State0] = Schedule[Env, In, Out] { type State = State0 }
}
sealed trait Decision
case object Done extends Decision
case class Continue(delay: Duration) extends Decision
trait DomainError
trait InvalidPassword extends DomainError
trait CouldNotDecrypt extends DomainError
trait Union[-In] {
type Out
def apply(in: In): Out
}
object Union extends UnionLowPriority1 {
type WithOut[In, Out0] = Union[In] { type Out = Out0 }
implicit def UnionEitherBoth[A]: Union.WithOut[Either[Either[A, A], Either[A, A]], A] =
new Union[Either[Either[A, A], Either[A, A]]] {
type Out = A
def apply(in: Either[Either[A, A], Either[A, A]]): A =
in.fold(_.merge, _.merge)
}
}
trait UnionLowPriority1 extends UnionLowPriority2 {
implicit def UnionEitherRight[A]: Union.WithOut[Either[A, Either[A, A]], A] =
new Union[Either[A, Either[A, A]]] {
type Out = A
def apply(in: Either[A, Either[A, A]]): A =
in.fold(identity, _.merge)
}
implicit def UnionEitherLeft[A]: Union.WithOut[Either[Either[A, A], A], A] =
new Union[Either[Either[A, A], A]] {
type Out = A
def apply(in: Either[Either[A, A], A]): A =
in.fold(_.merge, identity)
}
}
trait UnionLowPriority2 {
implicit def UnionEither[A]: Union.WithOut[Either[A, A], A] =
new Union[Either[A, A]] {
type Out = A
def apply(in: Either[A, A]): A =
in.merge
}
}
def unify[In](in: In)(implicit union: Union[In]): union.Out =
???
val either1: Either[InvalidPassword, CouldNotDecrypt] = ???
val either2: Either[InvalidPassword, Either[CouldNotDecrypt, InvalidPassword]] = ???
val either3: Either[Either[CouldNotDecrypt, InvalidPassword], InvalidPassword] = ???
val either4: Either[Either[CouldNotDecrypt, InvalidPassword], Either[CouldNotDecrypt, InvalidPassword]] = ???
// val either5: Either[InvalidPassword, Either[CouldNotDecrypt, Either[InvalidPassword, InvalidPassword]]] = ???
val result1 = unify(either1)
val result2 = unify(either2)
val result3 = unify(either3)
val result4 = unify(either4)
val result5: DomainError = result4
val myEither: Either[String, Int] = ???
val myOption: Option[List[Int]] = ???
val zio10: ZIO[Any, String, Int] = ZIO.from(myEither)
val zio11 = ZIO.from(either4)
}
trait Size[A] {
def size: Int
}
object Size extends SizeLowPriority {
implicit def tupleSize[A, B](implicit first: Size[A], second: Size[B]): Size[(A, B)] =
new Size[(A,B)] {
def size: Int =
first.size + second.size
}
}
trait SizeLowPriority {
implicit def anySize[A] = new Size[A] {
def size = 1
}
}
object SizeExamples extends scala.App {
def size[In](in: In)(implicit size: Size[In]): Unit =
println(s"$in -> ${size.size}")
val a = 12
val b = "Hello"
val ab = (a, b)
val c = true
val abab = (ab,ab)
val abababab = (abab,abab)
size(a)
size(b)
size(ab)
size(abab)
size(abababab)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment