Skip to content

Commit 9c12c3d

Browse files
committed
Added State traverse and sequence. Tested State for RNGs.
1 parent f90d4fe commit 9c12c3d

5 files changed

Lines changed: 92 additions & 63 deletions

File tree

core/src/main/java/fj/RNG.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,13 @@ public abstract class RNG {
1010
public abstract P2<RNG, Long> nextLong();
1111

1212
public P2<RNG, Integer> range(int low, int high) {
13-
return nextInt().map2(x -> (Math.abs(x) % (high - low + 1)) + low);
13+
return nextNatural().map2(x -> (x % (high - low + 1)) + low);
1414
}
1515

16+
17+
public P2<RNG, Integer> nextNatural() {
18+
return nextInt().map2(x -> x < 0 ? -(x + 1) : x);
19+
}
20+
21+
1622
}

core/src/main/java/fj/SimpleRNG.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ public P2<RNG, Integer> nextInt() {
2323
return P.p(p._1(), i);
2424
}
2525

26-
public P2<RNG, Long> nextLong() {
26+
27+
public P2<RNG, Long> nextLong() {
2728
P2<Long, Long> p = nextLong(seed);
2829
return P.p(new SimpleRNG(p._1()), p._2());
2930
}

core/src/main/java/fj/data/State.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import fj.*;
44

5+
import java.util.*;
6+
57
import static fj.P.p;
68

79
/**
@@ -96,4 +98,23 @@ public static <S, A> State<S, A> gets(F<S, A> f) {
9698
return State.<S>init().map(s -> f.f(s));
9799
}
98100

101+
/**
102+
* Evaluate each action in the sequence from left to right, and collect the results.
103+
*/
104+
public static <S, A> State<S, List<A>> sequence(List<State<S, A>> list) {
105+
return list.foldLeft((State<S, List<A>> acc, State<S, A> ma) ->
106+
acc.flatMap((List<A> xs) -> ma.map((A x) -> xs.snoc(x))
107+
), constant(List.<A>nil()));
108+
}
109+
110+
/**
111+
* Map each element of a structure to an action, evaluate these actions from left to right
112+
* and collect the results.
113+
*/
114+
public static <S, A, B> State<S, List<B>> traverse(List<A> list, F<A, State<S, B>> f) {
115+
return list.foldLeft((State<S, List<B>> acc, A a) ->
116+
acc.flatMap(bs -> f.f(a).map(b -> bs.snoc(b))
117+
), constant(List.<B>nil()));
118+
}
119+
99120
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package fj.data;
2+
3+
import fj.*;
4+
import fj.data.State;
5+
import fj.data.Stream;
6+
import org.junit.Assert;
7+
import org.junit.Test;
8+
9+
import static fj.data.Option.some;
10+
import static fj.data.Stream.unfold;
11+
12+
/**
13+
* Created by mperry on 4/08/2014.
14+
*/
15+
public class StateDemo_Rng {
16+
17+
static String expected1 = "<4,4,2,2,2,5,3,3,1,5>";
18+
static int size = 10;
19+
20+
static RNG initRNG() {
21+
return new SimpleRNG(1);
22+
}
23+
24+
@Test
25+
public void testUnfold() {
26+
Stream<Integer> s = unfold(r -> some(num(r).swap()), initRNG());
27+
Assert.assertTrue(s.take(size).toList().toString().equals(expected1));
28+
}
29+
30+
@Test
31+
public void testTransitions() {
32+
P2<List<State<RNG, Integer>>, State<RNG, Integer>> p = List.replicate(size, nextState()).foldLeft(
33+
(P2<List<State<RNG, Integer>>, State<RNG, Integer>> p2, F<State<RNG, Integer>, State<RNG, Integer>> f) -> {
34+
State<RNG, Integer> s = f.f(p2._2());
35+
return P.p(p2._1().snoc(p2._2()), s);
36+
}
37+
, P.p(List.nil(), defaultState())
38+
);
39+
List<Integer> ints = p._1().map(s -> s.eval(initRNG()));
40+
Assert.assertTrue(ints.toString().equals(expected1));
41+
}
42+
43+
44+
static P2<RNG, Integer> num(RNG r) {
45+
return r.range(1, 5);
46+
}
47+
48+
static State<RNG, Integer> defaultState() {
49+
return State.unit(s -> num(s));
50+
}
51+
52+
static F<State<RNG, Integer>, State<RNG, Integer>> nextState() {
53+
return s -> s.mapState(p2 -> num(p2._1()));
54+
}
55+
56+
@Test
57+
public void testSequence() {
58+
List<Integer> list = State.sequence(List.replicate(size, defaultState())).eval(initRNG());
59+
Assert.assertTrue(list.toString().equals(expected1));
60+
}
61+
62+
}

demo/src/main/java/fj/demo/StateDemo_Rng.java

Lines changed: 0 additions & 61 deletions
This file was deleted.

0 commit comments

Comments
 (0)