Skip to content

Instantly share code, notes, and snippets.

@Walexander
Last active February 15, 2023 14:34
Show Gist options
  • Save Walexander/8919d5777ea195c6b3e5640f86b5dba5 to your computer and use it in GitHub Desktop.
Save Walexander/8919d5777ea195c6b3e5640f86b5dba5 to your computer and use it in GitHub Desktop.
Prime number sieve using Effect streams
import * as Stream from '@effect/stream/Stream'
import * as Chunk from '@effect/data/Chunk'
import * as IO from '@effect/io/Effect'
import { pipe } from "~/lib";
const intsPlusPrimality = pipe(
Stream.range(1, Number.MAX_SAFE_INTEGER),
Stream.mapAccum(Chunk.empty<number>(), sieveChunk),
Stream.flatten
)
export const primes = Stream.map(
Stream.filter(intsPlusPrimality, ([,prime]) => prime),
([int]) => int
)
function sieveChunk(
primes: Chunk.Chunk<number>,
candidate: number,
): readonly [Chunk.Chunk<number>, Stream.Stream<never, never, [number, boolean]>] {
return candidate > 1 && Chunk.every(primes, prime => candidate % prime !== 0)
? [primes.append(candidate), Stream.succeed([candidate, true])]
: [primes, Stream.succeed([candidate, false])]
}
// Get 10 primes after the first 1000
export const main = pipe(
primes,
Stream.drop(1000),
Stream.take(10),
Stream.runCollect,
IO.timed,
IO.tap(([duration, [...ns]]) => IO.log(`collected
${ns.join(', ')}
duration: ${duration.millis}ms`)),
)
void IO.runSync(main)
timestamp=XX level=INFO fiber=#642 message="collected
7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, 8011, 8017
duration: 762ms"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment