Skip to content

Commit f89b61d

Browse files
peter-jerry-yebobzhang
authored andcommitted
refactor: introduce Source trait for random generator
1 parent 08f36bb commit f89b61d

File tree

3 files changed

+44
-17
lines changed

3 files changed

+44
-17
lines changed

random/README.mbt.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Internally, it uses the `Chacha8` cipher to generate random numbers. It is a cry
77
# Usage
88

99
```moonbit
10-
let r = @random.new()
10+
let r = @random.Rand::new(@random.chacha8())
1111
assert_eq!(r.uint(limit=10), 7)
1212
assert_eq!(r.uint(limit=10), 0)
1313
assert_eq!(r.uint(limit=10), 5)

random/random.mbt

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,36 +13,57 @@
1313
// limitations under the License.
1414

1515
///|
16-
/// Currently we only support [chacha8] as the source of randomness.
17-
struct Rand {
18-
src : @random_source.ChaCha8
16+
/// `Rand` is a pseudo-random number generator (PRNG) that provides various
17+
/// methods to generate random numbers of different types.
18+
type Rand &Source
19+
20+
///|
21+
/// The [Source] trait defines a method to generate random numbers.
22+
pub(open) trait Source {
23+
next(Self) -> UInt64
24+
}
25+
26+
///|
27+
impl Source for @random_source.ChaCha8 with next(self : @random_source.ChaCha8) -> UInt64 {
28+
for {
29+
let x = self.state.next()
30+
if x.1 {
31+
return x.0
32+
}
33+
self.state.refill()
34+
}
1935
}
2036

2137
///|
2238
/// Create a new random number generator with [seed].
2339
/// @alert unsafe "Panic if seed is not 32 bytes long"
40+
#deprecated("Use `Rand::new(chacha8())` instead")
2441
pub fn new(seed~ : Bytes = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ123456") -> Rand {
2542
if seed.length() != 32 {
2643
abort("seed must be 32 bytes long")
2744
}
28-
let src = @random_source.ChaCha8::new(seed)
29-
{ src, }
45+
@random_source.ChaCha8::new(seed) as &Source
46+
}
47+
48+
///|
49+
/// Create a new random number generator with [seed].
50+
/// @alert unsafe "Panic if seed is not 32 bytes long"
51+
pub fn chacha8(seed~ : Bytes = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ123456") -> &Source {
52+
if seed.length() != 32 {
53+
abort("seed must be 32 bytes long")
54+
}
55+
@random_source.ChaCha8::new(seed) as &Source
3056
}
3157

32-
///| @alert deprecated "use `@random.new` instead"
33-
pub fn Rand::new(seed~ : Bytes = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ123456") -> Rand {
34-
new(seed~)
58+
///|
59+
/// Create a new random number generator with a given [Gen] source.
60+
pub fn Rand::new(generator : &Source) -> Rand {
61+
generator
3562
}
3663

3764
///|
3865
fn next(self : Rand) -> UInt64 {
39-
for {
40-
let x = self.src.state.next()
41-
if x.1 {
42-
return x.0
43-
}
44-
self.src.state.refill()
45-
}
66+
self._.next()
4667
}
4768

4869
///|

random/random.mbti

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package "moonbitlang/core/random"
22

33
// Values
4+
fn chacha8(seed~ : Bytes = ..) -> &Source
5+
46
fn double(Rand) -> Double
57

68
fn float(Rand) -> Float
@@ -9,6 +11,7 @@ fn int(Rand, limit~ : Int = ..) -> Int
911

1012
fn int64(Rand, limit~ : Int64 = ..) -> Int64
1113

14+
#deprecated
1215
fn new(seed~ : Bytes = ..) -> Rand
1316

1417
fn shuffle(Rand, Int, (Int, Int) -> Unit) -> Unit
@@ -24,7 +27,7 @@ impl Rand {
2427
float(Self) -> Float
2528
int(Self, limit~ : Int = ..) -> Int
2629
int64(Self, limit~ : Int64 = ..) -> Int64
27-
new(seed~ : Bytes = ..) -> Self //deprecated
30+
new(&Source) -> Self
2831
shuffle(Self, Int, (Int, Int) -> Unit) -> Unit
2932
uint(Self, limit~ : UInt = ..) -> UInt
3033
uint64(Self, limit~ : UInt64 = ..) -> UInt64
@@ -33,4 +36,7 @@ impl Rand {
3336
// Type aliases
3437

3538
// Traits
39+
pub(open) trait Source {
40+
next(Self) -> UInt64
41+
}
3642

0 commit comments

Comments
 (0)