Skip to content

Instantly share code, notes, and snippets.

@nafg
Created October 20, 2020 19:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nafg/7e670b1bba50884067a724a3b3f05c2d to your computer and use it in GitHub Desktop.
Save nafg/7e670b1bba50884067a724a3b3f05c2d to your computer and use it in GitHub Desktop.
package chesednow.requests.sjs
import japgolly.scalajs.react.Callback
import japgolly.scalajs.react.vdom.VdomNode
import cats.implicits._
import monocle.{Iso, Prism}
trait PartialStateBase[V] {
type State
def initial: State
def prism: Prism[State, V]
type Settable = (State, V => Callback)
type Renderer = Settable => VdomNode
}
abstract class PartialState[V, S](override val initial: S) extends PartialStateBase[V] {
override type State = S
}
object PartialState {
def apply[V, S](empty: S)(getOption: S => Option[V])(reverseGet: V => S): PartialState[V, S] = {
new PartialState[V, S](empty) {
override val prism = Prism(getOption)(reverseGet)
}
}
def singleton[V](v: V): PartialState[V, Unit] =
apply(())(_ => Some(v))(_ => ())
def fromIso[V, S](iso: Iso[V, S]): PartialState[V, Option[S]] =
apply(Option.empty[S])(_.map(iso.reverseGet))(v => Some(iso.get(v)))
def option[V]: PartialState[V, Option[V]] =
apply(Option.empty[V])(identity)(Some(_))
def simple[V](empty: V): PartialState[V, V] =
apply(empty)(Some(_))(identity)
def tuple2[V, V1, V2, S1, S2](iso: Iso[V, (V1, V2)])
(c1: PartialState[V1, S1],
c2: PartialState[V2, S2]): PartialState[V, (S1, S2)] =
apply((c1.initial, c2.initial)) { case (s1, s2) =>
(c1.prism.getOption(s1), c2.prism.getOption(s2)).tupled.map(iso.reverseGet)
} { v =>
val (v1, v2) = iso.get(v)
(c1.prism.reverseGet(v1), c2.prism.reverseGet(v2))
}
def tuple3[V, V1, V2, V3, S1, S2, S3](iso: Iso[V, (V1, V2, V3)])
(c1: PartialState[V1, S1],
c2: PartialState[V2, S2],
c3: PartialState[V3, S3]): PartialState[V, (S1, S2, S3)] =
apply((c1.initial, c2.initial, c3.initial)) { case (s1, s2, s3) =>
(c1.prism.getOption(s1), c2.prism.getOption(s2), c3.prism.getOption(s3)).tupled.map(iso.reverseGet)
} { v =>
val (v1, v2, v3) = iso.get(v)
(c1.prism.reverseGet(v1), c2.prism.reverseGet(v2), c3.prism.reverseGet(v3))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment