@@ -184,9 +184,14 @@ object GenIso {
184
184
inline def unit [S ]: Iso [S , 1 ] = ~ Iso .implUnit[S ]
185
185
}
186
186
187
- trait Prism [S , A ] {
187
+ trait Prism [S , A ] { outer =>
188
188
def getOption (s : S ): Option [A ]
189
189
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
+ }
190
195
}
191
196
192
197
object Prism {
@@ -195,7 +200,20 @@ object Prism {
195
200
def apply (a : A ): S = app(a)
196
201
}
197
202
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
+ }
199
217
}
200
218
201
219
object GenPrism {
@@ -204,8 +222,8 @@ object GenPrism {
204
222
*
205
223
* Prism[Json, JStr]{
206
224
* case JStr(v) => Some(v)
207
- * case _ => None
225
+ * case _ => None
208
226
* }(jstr => jstr)
209
227
*/
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 ]
211
229
}
0 commit comments