Skip to content

Commit 22974df

Browse files
committed
add a tidbit about Mode#Self and Mode.current
1 parent fefa05f commit 22974df

File tree

1 file changed

+30
-0
lines changed

1 file changed

+30
-0
lines changed

docs/fallible_transformations/definition_of_transformer_fallible_and_mode.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ So a `Fallible` transformer takes a `Source` and gives back a `Dest` wrapped in
1111

1212
```scala
1313
sealed trait Mode[F[+x]] {
14+
type Self[+A] = F[A]
15+
1416
def pure[A](value: A): F[A]
1517

1618
def map[A, B](fa: F[A], f: A => B): F[B]
@@ -20,6 +22,14 @@ sealed trait Mode[F[+x]] {
2022
transformation: A => F[B]
2123
)(using factory: Factory[B, BColl]): F[BColl]
2224
}
25+
26+
object Mode {
27+
inline def current(using mode: Mode[?]): mode.type = mode
28+
29+
extension [F[+x], M <: Mode[F]](self: M) {
30+
inline def locally[A](inline f: M ?=> A): A = f(using self)
31+
}
32+
}
2333
```
2434

2535
Moving on to `Mode`, what exactly is it and why do we need it? So a `Mode[F]` is typeclass that gives us two bits of information:
@@ -48,3 +58,23 @@ Each one of these exposes one operation that dictates its approach to errors, `f
4858
For accumulating transformations `ducktape` provides instances for `Either` with any subtype of `Iterable` on the left side, so that eg. `Mode.Accumulating[[A] =>> Either[List[String], A]]` is available out of the box (under the subclass of `Mode.Accumulating.Either[String, List]`).
4959

5060
For fail fast transformations, instances for `Option` (`Mode.FailFast.Option`) and `Either` (`Mode.FailFast.Either`) are avaiable out of the box.
61+
62+
As for the purpose of the `Self[+A]` type member, it's to enable use cases like these:
63+
64+
```scala mdoc
65+
import io.github.arainko.ducktape.*
66+
67+
val source =
68+
(
69+
Right(1),
70+
Right("str"),
71+
Right(List(3, 3, 3)),
72+
Right(4)
73+
)
74+
75+
Mode.Accumulating.either[String, List].locally {
76+
source.fallibleTo[Tuple.InverseMap[source.type, Mode.current.Self]]
77+
}
78+
```
79+
80+
...where repeatedly referring to the `F` wrapper becomes really unwieldly - that type is known to the compiler at each call site so we make it work for us in conjunction with `Mode.current` which summons the `Mode[F]` instance in the current implicit scope.

0 commit comments

Comments
 (0)