Skip to content

Commit 5ace2a5

Browse files
committed
Implement GenPrism macro
1 parent fbf2c52 commit 5ace2a5

File tree

2 files changed

+27
-4
lines changed

2 files changed

+27
-4
lines changed

tests/run-with-compiler/i5941/macro_1.scala

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

192197
object 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

201219
object 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
}

tests/run-with-compiler/i5941/usage_2.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,10 @@ object Test {
3535

3636
// TODO: require whitebox macros
3737
// assert(GenIso.fields[Address].from((0, "a")) == Address(0, "a"))
38+
39+
val jNum: Prism[Json, Double] = GenPrism[Json, JNum] composeIso GenIso[JNum, Double]
40+
assert(jNum(3.5) == JNum(3.5))
41+
assert(jNum.getOption(JNum(3.5)) == Some(3.5))
42+
assert(jNum.getOption(JNull) == None)
3843
}
3944
}

0 commit comments

Comments
 (0)