-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinstances.ts
67 lines (60 loc) · 1.77 KB
/
instances.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import {Covariant as CO, FlatMap as FL, Monad as MD} from '@effect/typeclass'
import {Equivalence as EQ} from 'effect'
import {dual} from 'effect/Function'
import {TypeLambda} from 'effect/HKT'
import fc from 'fast-check'
import {testUnaryEquivalence} from './function.js'
/**
* Type lambda for the `fc.Arbitrary` datatype.
* @category type lambda
*/
export interface ArbitraryTypeLambda extends TypeLambda {
readonly type: fc.Arbitrary<this['Target']>
}
const map: CO.Covariant<ArbitraryTypeLambda>['map'] = dual(
2,
<A, B>(self: fc.Arbitrary<A>, f: (a: A) => B): fc.Arbitrary<B> =>
self.map(a => f(a)),
)
const flatMap: FL.FlatMap<ArbitraryTypeLambda>['flatMap'] = dual(
2,
<A, B>(
self: fc.Arbitrary<A>,
f: (a: A) => fc.Arbitrary<B>,
): fc.Arbitrary<B> => self.chain(a => f(a)),
)
/**
* Monad instance for `fc.Arbitrary`.
* @category fast-check
*/
export const Monad: MD.Monad<ArbitraryTypeLambda> = {
map,
imap: CO.imap<ArbitraryTypeLambda>(map),
flatMap,
of: fc.constant,
}
/**
* Get an equivalence for `fc.Arbitrary<A>` from an equivalence of `A`.
* Arbitraries are equal if they produce the same values for the same seeds.
* Note this only means we were unable to find a counter-example to the
* equivalence.
* @category fast-check
*/
export const getEquivalence = <A>(
equalsA: EQ.Equivalence<A>,
parameters?: fc.Parameters<number>,
): EQ.Equivalence<fc.Arbitrary<A>> => {
const sample =
(arbitrary: fc.Arbitrary<A>) =>
(seed: number): A => {
const [result] = fc.sample(arbitrary, {seed, numRuns: 1})
if (result === undefined) throw new Error('Could not sample.')
return result
}
return (self, that) =>
testUnaryEquivalence(
fc.integer(),
equalsA,
parameters,
)(sample(self), sample(that))
}