-
-
Notifications
You must be signed in to change notification settings - Fork 202
/
At.scala
57 lines (43 loc) · 1.96 KB
/
At.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package monocle.function
import monocle.{Iso, Lens}
import scala.annotation.implicitNotFound
import scala.collection.immutable.{ListMap, SortedMap}
/** Typeclass that defines a [[Lens]] from an `S` to an `A` at an index `I`
* @tparam S
* source of [[Lens]]
* @tparam I
* index
* @tparam A
* target of [[Lens]], `A` is supposed to be unique for a given pair `(S, I)`
*/
@implicitNotFound(
"Could not find an instance of At[${S},${I},${A}], please check Monocle instance location policy to " + "find out which import is necessary"
)
abstract class At[S, -I, A] extends Serializable {
def at(i: I): Lens[S, A]
}
trait AtFunctions {
def at[S, I, A](i: I)(implicit ev: At[S, I, A]): Lens[S, A] = ev.at(i)
/** delete a value associated with a key in a Map-like container */
def remove[S, I, A](i: I)(s: S)(implicit ev: At[S, I, Option[A]]): S =
ev.at(i).replace(None)(s)
}
object At extends AtFunctions {
def apply[S, I, A](lens: I => Lens[S, A]): At[S, I, A] = (i: I) => lens(i)
def apply[S, I, A](get: I => S => A)(set: I => A => S => S): At[S, I, A] =
(i: I) => Lens(get(i))(set(i))
/** lift an instance of [[At]] using an [[Iso]] */
def fromIso[S, U, I, A](iso: Iso[S, U])(implicit ev: At[U, I, A]): At[S, I, A] =
At((i: I) => iso.andThen(ev.at(i)))
/* ************** */
/* Std instances */
/* ************** */
implicit def atSortedMap[K, V]: At[SortedMap[K, V], K, Option[V]] =
At(i => Lens((_: SortedMap[K, V]).get(i))(optV => map => optV.fold(map - i)(v => map + (i -> v))))
implicit def atListMap[K, V]: At[ListMap[K, V], K, Option[V]] =
At(i => Lens((_: ListMap[K, V]).get(i))(optV => map => optV.fold(map - i)(v => map + (i -> v))))
implicit def atMap[K, V]: At[Map[K, V], K, Option[V]] =
At(i => Lens((_: Map[K, V]).get(i))(optV => map => optV.fold(map - i)(v => map + (i -> v))))
implicit def atSet[A]: At[Set[A], A, Boolean] =
At(a => Lens((_: Set[A]).contains(a))(b => set => if (b) set + a else set - a))
}