Skip to content

Commit 607578b

Browse files
authored
Merge pull request #1029 from aol/betterWriterTypeclassInstance
better Writer Typeclass Instance
2 parents 27d97ac + 56a2586 commit 607578b

File tree

1 file changed

+53
-74
lines changed

1 file changed

+53
-74
lines changed

Diff for: cyclops-pure/src/main/java/cyclops/instances/control/WriterInstances.java

+53-74
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import cyclops.hkt.Product;
1616
import cyclops.typeclasses.InstanceDefinitions;
1717
import cyclops.typeclasses.functor.Functor;
18+
import lombok.AllArgsConstructor;
1819
import lombok.experimental.UtilityClass;
1920

2021
import java.util.function.Function;
@@ -81,12 +82,12 @@ public <T, R> Monad<Higher<writer, W>> monad() {
8182

8283
@Override
8384
public <T, R> Option<MonadZero<Higher<writer, W>>> monadZero() {
84-
return Maybe.nothing();
85+
return Option.none();
8586
}
8687

8788
@Override
8889
public <T> Option<MonadPlus<Higher<writer, W>>> monadPlus() {
89-
return Maybe.nothing();
90+
return Option.none();
9091
}
9192

9293
@Override
@@ -96,7 +97,7 @@ public <T> MonadRec<Higher<writer, W>> monadRec() {
9697

9798
@Override
9899
public <T> Option<MonadPlus<Higher<writer, W>>> monadPlus(MonoidK<Higher<writer, W>> m) {
99-
return Maybe.nothing();
100+
return Option.none();
100101
}
101102

102103
@Override
@@ -111,109 +112,87 @@ public <T> Foldable<Higher<writer, W>> foldable() {
111112

112113
@Override
113114
public <T> Option<Comonad<Higher<writer, W>>> comonad() {
114-
return Maybe.nothing();
115+
return Option.none();
115116
}
116117

117118
@Override
118119
public <T> Option<Unfoldable<Higher<writer, W>>> unfoldable() {
119-
return Maybe.nothing();
120+
return Option.none();
120121
}
121122
};
122123
}
123-
public static <W> Functor<Higher<writer, W>> functor() {
124-
return new Functor<Higher<writer, W>>() {
125-
@Override
126-
public <T, R> Higher<Higher<writer, W>, R> map(Function<? super T, ? extends R> fn, Higher<Higher<writer, W>, T> ds) {
127-
return narrowK(ds).map(fn);
128-
}
129-
};
130-
}
131-
public static <W> Pure<Higher<writer, W>> unit(Monoid<W> monoid) {
132-
return new Pure<Higher<writer, W>>() {
133-
134-
@Override
135-
public <T> Higher<Higher<writer, W>, T> unit(T value) {
136-
return Writer.writer(value,monoid);
137-
}
138-
};
139-
}
140-
public static <W> Applicative<Higher<writer, W>> applicative(Monoid<W> monoid) {
141-
return new Applicative<Higher<writer, W>>() {
142124

143-
@Override
144-
public <T, R> Higher<Higher<writer, W>, R> ap(Higher<Higher<writer, W>, ? extends Function<T, R>> fn, Higher<Higher<writer, W>, T> apply) {
145-
Writer<W, ? extends Function<T, R>> f = narrowK(fn);
146-
Writer<W, T> ap = narrowK(apply);
147-
return f.flatMap(fn1->ap.map(a->fn1.apply(a)));
148-
}
125+
@AllArgsConstructor
126+
public static class WriterTypeclasses<W> implements Monad<Higher<writer, W>>,
127+
TraverseByTraverse<Higher<writer, W>>,
128+
MonadRec<Higher<writer, W>> {
149129

150-
@Override
151-
public <T, R> Higher<Higher<writer, W>, R> map(Function<? super T, ? extends R> fn, Higher<Higher<writer, W>, T> ds) {
152-
return WriterInstances.<W>functor().map(fn,ds);
153-
}
130+
private final Monoid<W> monoid;
154131

155132
@Override
156-
public <T> Higher<Higher<writer, W>, T> unit(T value) {
157-
return WriterInstances.<W>unit(monoid).unit(value);
158-
}
159-
};
160-
}
161-
public static <W> Monad<Higher<writer, W>> monad(Monoid<W> monoid) {
162-
return new Monad<Higher<writer, W>>() {
163-
164-
165-
@Override
166-
public <T, R> Higher<Higher<writer, W>, R> ap(Higher<Higher<writer, W>, ? extends Function<T, R>> fn, Higher<Higher<writer, W>, T> apply) {
167-
return WriterInstances.<W>applicative(monoid).ap(fn,apply);
133+
public <T, R> Higher<Higher<writer, W>, R> flatMap(Function<? super T, ? extends Higher<Higher<writer, W>, R>> fn, Higher<Higher<writer, W>, T> ds) {
134+
return narrowK(ds).flatMap(fn.andThen(h->narrowK(h)));
168135
}
169136

170137
@Override
171-
public <T, R> Higher<Higher<writer, W>, R> map(Function<? super T, ? extends R> fn, Higher<Higher<writer, W>, T> ds) {
172-
return WriterInstances.<W>functor().map(fn,ds);
173-
}
138+
public <T, R> Higher<Higher<writer, W>, R> tailRec(T initial, Function<? super T, ? extends Higher<Higher<writer, W>, ? extends Either<T, R>>> fn) {
139+
Writer<W,? extends Either<T, R>> next[] = new Writer[1];
140+
next[0] = Writer.writer(Either.left(initial),monoid);
174141

175-
@Override
176-
public <T> Higher<Higher<writer, W>, T> unit(T value) {
177-
return WriterInstances.<W>unit(monoid).unit(value);
142+
boolean cont = true;
143+
do {
144+
cont = next[0].fold((p, __) -> p._1().fold(s -> {
145+
next[0] = narrowK(fn.apply(s));
146+
return true;
147+
}, pr -> false));
148+
} while (cont);
149+
return next[0].map(x->x.orElse(null));
178150
}
179151

180-
@Override
181-
public <T, R> Higher<Higher<writer, W>, R> flatMap(Function<? super T, ? extends Higher<Higher<writer, W>, R>> fn, Higher<Higher<writer, W>, T> ds) {
182-
return narrowK(ds).flatMap(fn.andThen(h->narrowK(h)));
183-
}
184-
};
185-
}
186-
public static <W> Traverse<Higher<writer, W>> traverse(Monoid<W> monoid) {
187-
return new Traverse<Higher<writer, W>>() {
188152
@Override
189153
public <C2, T, R> Higher<C2, Higher<Higher<writer, W>, R>> traverseA(Applicative<C2> applicative, Function<? super T, ? extends Higher<C2, R>> fn, Higher<Higher<writer, W>, T> ds) {
190-
Writer<W, T> w = narrowK(ds);
191-
Higher<C2, R> r = w.fold((t, m) -> fn.apply(t._1()));
192-
Higher<C2, Higher<Higher<writer, W>, R>> x = applicative.map_(r, t -> widen(Writer.writer(t, monoid)));
193-
return x;
194-
195-
}
196-
197-
@Override
198-
public <C2, T> Higher<C2, Higher<Higher<writer, W>, T>> sequenceA(Applicative<C2> applicative, Higher<Higher<writer, W>, Higher<C2, T>> ds) {
199-
return traverseA(applicative,Function.identity(),ds);
154+
Writer<W, T> w = narrowK(ds);
155+
Higher<C2, R> r = w.fold((t, m) -> fn.apply(t._1()));
156+
Higher<C2, Higher<Higher<writer, W>, R>> x = applicative.map_(r, t -> widen(Writer.writer(t, monoid)));
157+
return x;
200158
}
201159

202160
@Override
203161
public <T, R> Higher<Higher<writer, W>, R> ap(Higher<Higher<writer, W>, ? extends Function<T, R>> fn, Higher<Higher<writer, W>, T> apply) {
204-
return WriterInstances.applicative(monoid).ap(fn,apply);
162+
Writer<W, ? extends Function<T, R>> f = narrowK(fn);
163+
Writer<W, T> ap = narrowK(apply);
164+
return f.flatMap(fn1->ap.map(a->fn1.apply(a)));
205165
}
206166

207167
@Override
208168
public <T> Higher<Higher<writer, W>, T> unit(T value) {
209-
return WriterInstances.unit(monoid).unit(value);
169+
return Writer.writer(value,monoid);
210170
}
211171

212172
@Override
213173
public <T, R> Higher<Higher<writer, W>, R> map(Function<? super T, ? extends R> fn, Higher<Higher<writer, W>, T> ds) {
214-
return WriterInstances.<W>functor().map(fn,ds);
174+
return narrowK(ds).map(fn);
175+
}
176+
}
177+
public static <W> Functor<Higher<writer, W>> functor() {
178+
return new Functor<Higher<writer, W>>() {
179+
@Override
180+
public <T, R> Higher<Higher<writer, W>, R> map(Function<? super T, ? extends R> fn, Higher<Higher<writer, W>, T> ds) {
181+
return narrowK(ds).map(fn);
215182
}
216183
};
184+
}
185+
public static <W> Pure<Higher<writer, W>> unit(Monoid<W> monoid) {
186+
return new WriterTypeclasses<>(monoid);
187+
}
188+
public static <W> Applicative<Higher<writer, W>> applicative(Monoid<W> monoid) {
189+
return new WriterTypeclasses<>(monoid);
190+
}
191+
public static <W> Monad<Higher<writer, W>> monad(Monoid<W> monoid) {
192+
return new WriterTypeclasses<>(monoid);
193+
}
194+
public static <W> Traverse<Higher<writer, W>> traverse(Monoid<W> monoid) {
195+
return new WriterTypeclasses<>(monoid);
217196
}
218197

219198
public static <W> Foldable<Higher<writer,W>> foldable() {
@@ -237,7 +216,7 @@ public <T, R> R foldMap(Monoid<R> mb, Function<? super T, ? extends R> fn, Highe
237216
}
238217
};
239218
}
240-
public static <W, T, R> MonadRec<Higher<writer, W>> monadRec(Monoid<W> monoid) {
219+
public static <W> MonadRec<Higher<writer, W>> monadRec(Monoid<W> monoid) {
241220
return new MonadRec<Higher<writer, W>>() {
242221
@Override
243222
public <T, R> Higher<Higher<writer, W>, R> tailRec(T initial, Function<? super T, ? extends Higher<Higher<writer, W>, ? extends Either<T, R>>> fn) {

0 commit comments

Comments
 (0)