1
+ package kategory
2
+
3
+ import io.kotlintest.properties.Gen
4
+ import io.kotlintest.properties.forAll
5
+
6
+ object ApplicativeErrorLaws {
7
+
8
+ inline fun <reified F > laws (AP : ApplicativeError <F , Throwable > = applicativeError<F , Throwable >(), EQERR : Eq <HK <F , Int >>, EQ_EITHER : Eq <HK <F , Either <Throwable , Int >>>, EQ : Eq <HK <F , Int >> = EQERR ): List <Law > =
9
+ ApplicativeLaws .laws(AP , EQ ) + listOf (
10
+ Law (" Applicative Error Laws: handle" , { applicativeErrorHandle(AP , EQERR ) }),
11
+ Law (" Applicative Error Laws: handle with for error" , { applicativeErrorHandleWith(AP , EQERR ) }),
12
+ Law (" Applicative Error Laws: handle with for success" , { applicativeErrorHandleWithPure(AP , EQERR ) }),
13
+ Law (" Applicative Error Laws: attempt for error" , { applicativeErrorAttemptError(AP , EQ_EITHER ) }),
14
+ Law (" Applicative Error Laws: attempt for success" , { applicativeErrorAttemptSuccess(AP , EQ_EITHER ) }),
15
+ Law (" Applicative Error Laws: attempt fromEither consistent with pure" , { applicativeErrorAttemptFromEitherConsistentWithPure(AP , EQ_EITHER ) }),
16
+ Law (" Applicative Error Laws: catch captures errors" , { applicativeErrorCatch(AP , EQERR ) })
17
+ )
18
+
19
+ inline fun <reified F > applicativeErrorHandle (AP : ApplicativeError <F , Throwable > = applicativeError<F , Throwable >(), EQ : Eq <HK <F , Int >>): Unit =
20
+ forAll(genFunctionAToB<Throwable , Int >(Gen .int()), genThrowable(), { f: (Throwable ) -> Int , e: Throwable ->
21
+ AP .handleError(AP .raiseError<Int >(e), f).equalUnderTheLaw(AP .pure(f(e)), EQ )
22
+ })
23
+
24
+ inline fun <reified F > applicativeErrorHandleWith (AP : ApplicativeError <F , Throwable > = applicativeError<F , Throwable >(), EQ : Eq <HK <F , Int >>): Unit =
25
+ forAll(genFunctionAToB<Throwable , HK <F , Int >>(genApplicative(Gen .int(), AP )), genThrowable(), { f: (Throwable ) -> HK <F , Int >, e: Throwable ->
26
+ AP .handleErrorWith(AP .raiseError<Int >(e), f).equalUnderTheLaw(f(e), EQ )
27
+ })
28
+
29
+ inline fun <reified F > applicativeErrorHandleWithPure (AP : ApplicativeError <F , Throwable > = applicativeError<F , Throwable >(), EQ : Eq <HK <F , Int >>): Unit =
30
+ forAll(genFunctionAToB<Throwable , HK <F , Int >>(genApplicative(Gen .int(), AP )), Gen .int(), { f: (Throwable ) -> HK <F , Int >, a: Int ->
31
+ AP .handleErrorWith(AP .pure(a), f).equalUnderTheLaw(AP .pure(a), EQ )
32
+ })
33
+
34
+ inline fun <reified F > applicativeErrorAttemptError (AP : ApplicativeError <F , Throwable > = applicativeError<F , Throwable >(), EQ : Eq <HK <F , Either <Throwable , Int >>>): Unit =
35
+ forAll(genThrowable(), { e: Throwable ->
36
+ AP .attempt(AP .raiseError<Int >(e)).equalUnderTheLaw(AP .pure(e.left()), EQ )
37
+ })
38
+
39
+ inline fun <reified F > applicativeErrorAttemptSuccess (AP : ApplicativeError <F , Throwable > = applicativeError<F , Throwable >(), EQ : Eq <HK <F , Either <Throwable , Int >>>): Unit =
40
+ forAll(Gen .int(), { a: Int ->
41
+ AP .attempt(AP .pure(a)).equalUnderTheLaw(AP .pure(a.right()), EQ )
42
+ })
43
+
44
+ inline fun <reified F > applicativeErrorAttemptFromEitherConsistentWithPure (AP : ApplicativeError <F , Throwable > = applicativeError<F , Throwable >(), EQ : Eq <HK <F , Either <Throwable , Int >>>): Unit =
45
+ forAll(genEither(genThrowable(), Gen .int()), { either: Either <Throwable , Int > ->
46
+ AP .attempt(AP .fromEither(either)).equalUnderTheLaw(AP .pure(either), EQ )
47
+ })
48
+
49
+ inline fun <reified F > applicativeErrorCatch (AP : ApplicativeError <F , Throwable > = applicativeError<F , Throwable >(), EQ : Eq <HK <F , Int >>): Unit =
50
+ forAll(genEither(genThrowable(), Gen .int()), { either: Either <Throwable , Int > ->
51
+ AP .catch ({ either.fold({ throw it }, { it }) }).equalUnderTheLaw(either.fold({ AP .raiseError<Int >(it) }, { AP .pure(it) }), EQ )
52
+ })
53
+
54
+ }
0 commit comments