@@ -16,39 +16,48 @@ import cats.syntax.all.*
1616import clue .data .syntax .*
1717import io .circe .*
1818import io .circe .syntax .*
19+ import monocle .Prism
1920
2021import scala .annotation .tailrec
2122
2223sealed trait Input [+ A ] {
2324 def map [B ](f : A => B ): Input [B ] =
24- this match {
25+ this match
2526 case Ignore => Ignore
2627 case Unassign => Unassign
2728 case Assign (a) => Assign (f(a))
28- }
2929
3030 def fold [B ](fundef : => B , funset : => B , fset : A => B ): B =
31- this match {
31+ this match
3232 case Ignore => fundef
3333 case Unassign => funset
3434 case Assign (a) => fset(a)
35- }
3635
3736 def flatten [B ](implicit ev : A <:< Input [B ]): Input [B ] =
38- this match {
37+ this match
3938 case Ignore => Ignore
4039 case Unassign => Unassign
4140 case Assign (a) => a
42- }
4341
4442 def flatMap [B ](f : A => Input [B ]): Input [B ] =
4543 map(f).flatten
4644
4745 def toOption : Option [A ] =
48- this match {
46+ this match
4947 case Assign (a) => a.some
5048 case _ => none
51- }
49+
50+ def orElse [B >: A ](that : => Input [B ]): Input [B ] =
51+ this match
52+ case Ignore => that
53+ case Unassign => that
54+ case Assign (a) => Assign (a)
55+
56+ def orAssign [B >: A ](that : => B ): Input [B ] =
57+ orElse(Assign (that))
58+
59+ inline def isAssigned : Boolean =
60+ fold(false , false , _ => true )
5261}
5362
5463case object Ignore extends Input [Nothing ]
@@ -68,16 +77,17 @@ object Input {
6877 def ignore [A ]: Input [A ] = Ignore
6978
7079 def orIgnore [A ](opt : Option [A ]): Input [A ] =
71- opt match {
80+ opt match
7281 case Some (a) => Assign (a)
7382 case None => Ignore
74- }
7583
7684 def orUnassign [A ](opt : Option [A ]): Input [A ] =
77- opt match {
85+ opt match
7886 case Some (a) => Assign (a)
7987 case None => Unassign
80- }
88+
89+ def assignValue [A ]: Prism [Input [A ], A ] =
90+ optics.pAssign[A , A ]
8191
8292 given [A : Eq ]: Eq [Input [A ]] =
8393 new Eq [Input [A ]]:
@@ -123,38 +133,34 @@ object Input {
123133
124134 @ tailrec
125135 override def tailRecM [A , B ](a : A )(f : A => Input [Either [A , B ]]): Input [B ] =
126- f(a) match {
136+ f(a) match
127137 case Ignore => Ignore
128138 case Unassign => Unassign
129139 case Assign (Left (a)) => tailRecM(a)(f)
130140 case Assign (Right (b)) => Assign (b)
131- }
132141
133142 override def flatMap [A , B ](fa : Input [A ])(f : A => Input [B ]): Input [B ] =
134143 fa.flatMap(f)
135144
136145 override def traverse [F [_], A , B ](
137146 fa : Input [A ]
138147 )(f : A => F [B ])(using F : Applicative [F ]): F [Input [B ]] =
139- fa match {
148+ fa match
140149 case Ignore => F .pure(Ignore )
141150 case Unassign => F .pure(Unassign )
142151 case Assign (a) => F .map(f(a))(Assign (_))
143- }
144152
145153 override def foldLeft [A , B ](fa : Input [A ], b : B )(f : (B , A ) => B ): B =
146- fa match {
154+ fa match
147155 case Ignore => b
148156 case Unassign => b
149157 case Assign (a) => f(b, a)
150- }
151158
152159 override def foldRight [A , B ](fa : Input [A ], lb : Eval [B ])(f : (A , Eval [B ]) => Eval [B ]): Eval [B ] =
153- fa match {
160+ fa match
154161 case Ignore => lb
155162 case Unassign => lb
156163 case Assign (a) => f(a, lb)
157- }
158164
159165 override def functor : Functor [Input ] = this
160166
0 commit comments