Skip to content

Commit e66dc31

Browse files
committed
Add validation to the strawman
1 parent b03a742 commit e66dc31

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

tests/run/errorhandling/Result.scala

+22-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,24 @@ object Result:
2828
case Ok(x) => f(x)
2929
case err: Err[_] => err
3030

31+
/** Validate both `r` and `other`; return a pair of successes or a list of failures. */
32+
def * [U](other: Result[U, E]): Result[(T, U), List[E]] = (r, other) match
33+
case (Ok(x), Ok(y)) => Ok((x, y))
34+
case (Ok(_), Err(e)) => Err(e :: Nil)
35+
case (Err(e), Ok(_)) => Err(e :: Nil)
36+
case (Err(e1), Err(e2)) => Err(e1 :: e2 :: Nil)
37+
38+
/** Validate both `r` and `other`; return a tuple of successes or a list of failures.
39+
* Unlike with `*`, the right hand side `other` must be a `Result` returning a `Tuple`,
40+
* and the left hand side is added to it. See `Result.empty` for a convenient
41+
* right unit of chains of `*:`s.
42+
*/
43+
def *: [U <: Tuple](other: Result[U, List[E]]): Result[T *: U, List[E]] = (r, other) match
44+
case (Ok(x), Ok(ys)) => Ok(x *: ys)
45+
case (Ok(_), es: Err[?]) => es
46+
case (Err(e), Ok(_)) => Err(e :: Nil)
47+
case (Err(e), Err(es)) => Err(e :: es)
48+
3149
/** Simlar to `Try`: Convert exceptions raised by `body` to `Err`s.
3250
* In principle, `Try[T]` should be equivalent to `Result[T, Exception]`.
3351
* Note that we do not want to catch and reify all Throwables.
@@ -37,9 +55,12 @@ object Result:
3755
* (Generally, the focus on `Throwable` in Scala libraries is a mistake.
3856
* Use `Exception` instead, as it was meant to in Java.)
3957
*/
40-
def apply[T](body: => T): Result[T, Exception] =
58+
inline def apply[T](body: => T): Result[T, Exception] =
4159
try Ok(body)
4260
catch case ex: Exception => Err(ex)
61+
62+
/** Right unit for chains of `*:`s. Returns an `Ok` with an `EmotyTuple` value. */
63+
def empty: Result[EmptyTuple, Nothing] = Ok(EmptyTuple)
4364
end Result
4465

4566
/** A prompt for `_.?`. It establishes a boundary to which `_.?` returns */

tests/run/errorhandling/Test.scala

+8
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,14 @@ def resultTest() =
6262
assertFail(sumRoots(List("1", "-2", "4")), "cannot take sqrt of negative")
6363
assertFail(sumRoots(List()), "list is empty")
6464
assertFail(sumRoots(List("1", "3ab")), "NumberFormatException")
65+
val xs = sumRoots(List("1", "-2", "4")) *: sumRoots(List()) *: sumRoots(List("1", "3ab")) *: Result.empty
66+
xs match
67+
case Err(msgs) => assert(msgs.length == 3)
68+
case _ => assert(false)
69+
val ys = sumRoots(List("1", "2", "4")) *: sumRoots(List("1")) *: sumRoots(List("2")) *: Result.empty
70+
ys match
71+
case Ok((a, b, c)) => // ok
72+
case _ => assert(false)
6573

6674
@main def Test =
6775
breakTest()

tests/run/errorhandling/kostas.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ object PersonCsvParserIgnoreErrors:
1717
def parse(csv: Seq[String]): Seq[Person] =
1818
for
1919
line <- csv
20-
columns = line.split(",")x
20+
columns = line.split(",")
2121
parsed <- parseColumns(columns)
2222
yield
2323
parsed

0 commit comments

Comments
 (0)