@@ -184,9 +184,14 @@ object GenIso {
184184 inline def unit [S ]: Iso [S , 1 ] = ~ Iso .implUnit[S ]
185185}
186186
187- trait Prism [S , A ] {
187+ trait Prism [S , A ] { outer =>
188188 def getOption (s : S ): Option [A ]
189189 def apply (a : A ): S
190+
191+ def composeIso [B ](iso : Iso [A , B ]): Prism [S , B ] = new Prism {
192+ def getOption (s : S ): Option [B ] = outer.getOption(s).map(a => iso.to(a))
193+ def apply (b : B ): S = outer(iso.from(b))
194+ }
190195}
191196
192197object Prism {
@@ -195,7 +200,20 @@ object Prism {
195200 def apply (a : A ): S = app(a)
196201 }
197202
198- def impl [S : Type , A : Type ](implicit refl : Reflection ): Expr [Prism [S , A ]] = ???
203+ def impl [S : Type , A <: S : Type ](implicit refl : Reflection ): Expr [Prism [S , A ]] = {
204+ import refl ._
205+ import util ._
206+ import quoted .Toolbox .Default ._
207+
208+ val tpS = typeOf[S ]
209+ val tpA = typeOf[A ]
210+
211+ ' {
212+ val get = (p : S ) => if (p.isInstanceOf [A ]) Some (p.asInstanceOf [A ]) else None
213+ val app = (p : A ) => p
214+ apply(get)(app)
215+ }
216+ }
199217}
200218
201219object GenPrism {
@@ -204,8 +222,8 @@ object GenPrism {
204222 *
205223 * Prism[Json, JStr]{
206224 * case JStr(v) => Some(v)
207- * case _ => None
225+ * case _ => None
208226 * }(jstr => jstr)
209227 */
210- inline def apply [S , A ]: Prism [S , A ] = ~ Prism .impl[S , A ]
228+ inline def apply [S , A <: S ]: Prism [S , A ] = ~ Prism .impl[S , A ]
211229}
0 commit comments