@@ -12,7 +12,7 @@ import kategory.Eval.Companion.always
12
12
*
13
13
* Beyond these it provides many other useful methods related to folding over F<A> values.
14
14
*/
15
- interface Foldable <F > : Typeclass {
15
+ interface Foldable <in F > : Typeclass {
16
16
17
17
/* *
18
18
* Left associative fold on F using the provided function.
@@ -37,7 +37,8 @@ interface Foldable<F> : Typeclass {
37
37
*
38
38
* Note: will not terminate for infinite-sized collections.
39
39
*/
40
- fun <A > size (ml : Monoid <Long >, fa : HK <F , A >): Long = foldMap(ml, fa)({ _ -> 1L })
40
+ fun <A > size (ml : Monoid <Long >, fa : HK <F , A >): Long =
41
+ foldMap(ml, fa, { _ -> 1L })
41
42
42
43
/* *
43
44
* Fold implemented using the given Monoid<A> instance.
@@ -53,8 +54,8 @@ interface Foldable<F> : Typeclass {
53
54
/* *
54
55
* Fold implemented by mapping A values into B and then combining them using the given Monoid<B> instance.
55
56
*/
56
- fun <A , B > foldMap (mb : Monoid <B >, fa : HK <F , A >): ( f: (A ) -> B ) -> B =
57
- { f : ( A ) -> B -> foldL(fa, mb.empty(), { b, a -> mb.combine(b, f(a)) }) }
57
+ fun <A , B > foldMap (mb : Monoid <B >, fa : HK <F , A >, f : (A ) -> B ): B =
58
+ foldL(fa, mb.empty(), { b, a -> mb.combine(b, f(a)) })
58
59
59
60
/* *
60
61
* Left associative monadic folding on F.
@@ -63,18 +64,16 @@ interface Foldable<F> : Typeclass {
63
64
* Certain structures are able to implement this in such a way that folds can be short-circuited (not traverse the
64
65
* entirety of the structure), depending on the G result produced at a given step.
65
66
*/
66
- fun <G , A , B > foldM (MG : Monad <G >, fa : HK <F , A >, z : B , f : (B , A ) -> HK <G , B >): HK <G , B > {
67
- return foldL(fa, MG .pure(z), { gb, a -> MG .flatMap(gb) { f(it, a) } })
68
- }
67
+ fun <G , A , B > foldM (MG : Monad <G >, fa : HK <F , A >, z : B , f : (B , A ) -> HK <G , B >): HK <G , B > =
68
+ foldL(fa, MG .pure(z), { gb, a -> MG .flatMap(gb) { f(it, a) } })
69
69
70
70
/* *
71
71
* Monadic folding on F by mapping A values to G<B>, combining the B values using the given Monoid<B> instance.
72
72
*
73
73
* Similar to foldM, but using a Monoid<B>.
74
74
*/
75
- fun <G , A , B > foldMapM (MG : Monad <G >, bb : Monoid <B >, fa : HK <F , A >, f : (A ) -> HK <G , B >) : HK <G , B > {
76
- return foldM(MG , fa, bb.empty(), { b, a -> MG .map(f(a)) { bb.combine(b, it) } })
77
- }
75
+ fun <G , A , B > foldMapM (MG : Monad <G >, bb : Monoid <B >, fa : HK <F , A >, f : (A ) -> HK <G , B >) : HK <G , B > =
76
+ foldM(MG , fa, bb.empty(), { b, a -> MG .map(f(a)) { bb.combine(b, it) } })
78
77
79
78
/* *
80
79
* Traverse F<A> using Applicative<G>.
@@ -95,28 +94,38 @@ interface Foldable<F> : Typeclass {
95
94
fun <G , A > sequence_ (ag : Applicative <G >, fga : HK <F , HK <G , A >>): HK <G , Unit > =
96
95
traverse_(ag, fga, { it })
97
96
97
+ /* *
98
+ * Find the first element matching the predicate, if one exists.
99
+ */
100
+ fun <A > find (fa : HK <F , A >, f : (A ) -> Boolean ): Option <A > =
101
+ foldR(fa, Eval .now<Option <A >>(Option .None ), { a, lb ->
102
+ if (f(a)) Eval .now(Option .Some (a)) else lb
103
+ }).value()
104
+
98
105
/* *
99
106
* Check whether at least one element satisfies the predicate.
100
107
*
101
108
* If there are no elements, the result is false.
102
109
*/
103
- fun <A > exists (fa : HK <F , A >): ( p: (A ) -> Boolean ) -> Boolean =
104
- { p : ( A ) -> Boolean -> foldR(fa, Eval .False , { a, lb -> if (p(a)) Eval .True else lb }).value() }
110
+ fun <A > exists (fa : HK <F , A >, p : (A ) -> Boolean ): Boolean =
111
+ foldR(fa, Eval .False , { a, lb -> if (p(a)) Eval .True else lb }).value()
105
112
106
113
/* *
107
114
* Check whether all elements satisfy the predicate.
108
115
*
109
116
* If there are no elements, the result is true.
110
117
*/
111
- fun <A > forall (fa : HK <F , A >): ( p: (A ) -> Boolean ) -> Boolean =
112
- { p : ( A ) -> Boolean -> foldR(fa, Eval .True , { a, lb -> if (p(a)) lb else Eval .False }).value() }
118
+ fun <A > forall (fa : HK <F , A >, p : (A ) -> Boolean ): Boolean =
119
+ foldR(fa, Eval .True , { a, lb -> if (p(a)) lb else Eval .False }).value()
113
120
114
121
/* *
115
122
* Returns true if there are no elements. Otherwise false.
116
123
*/
117
- fun <A > isEmpty (fa : HK <F , A >): Boolean = foldR(fa, Eval .True , { _, _ -> Eval .False }).value()
124
+ fun <A > isEmpty (fa : HK <F , A >): Boolean =
125
+ foldR(fa, Eval .True , { _, _ -> Eval .False }).value()
118
126
119
- fun <A > nonEmpty (fa : HK <F , A >): Boolean = ! isEmpty(fa)
127
+ fun <A > nonEmpty (fa : HK <F , A >): Boolean =
128
+ ! isEmpty(fa)
120
129
121
130
companion object {
122
131
fun <A , B > iterateRight (it : Iterator <A >, lb : Eval <B >): (f: (A , Eval <B >) -> Eval <B >) -> Eval <B > = {
0 commit comments