/
Applicative.purs
54 lines (42 loc) · 1.5 KB
/
Applicative.purs
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
module Test.QuickCheck.Laws.Control.Applicative where
import Prelude
import Data.Function as F
import Effect (Effect)
import Effect.Console (log)
import Test.QuickCheck (quickCheck')
import Test.QuickCheck.Arbitrary (class Arbitrary)
import Test.QuickCheck.Laws (A, B, C)
import Type.Proxy (Proxy2)
-- | - Identity: `(pure identity) <*> v = v`
-- | - Composition: `(pure (<<<)) <*> f <*> g <*> h = f <*> (g <*> h)`
-- | - Homomorphism: `(pure f) <*> (pure x) = pure (f x)`
-- | - Interchange: `u <*> (pure y) = (pure ($ y)) <*> u`
checkApplicative
∷ ∀ f
. Applicative f
⇒ Arbitrary (f A)
⇒ Arbitrary (f (A → B))
⇒ Arbitrary (f (B → C))
⇒ Eq (f A)
⇒ Eq (f B)
⇒ Eq (f C)
⇒ Proxy2 f
→ Effect Unit
checkApplicative _ = do
log "Checking 'Identity' law for Applicative"
quickCheck' 1000 identity
log "Checking 'Composition' law for Applicative"
quickCheck' 1000 composition
log "Checking 'Homomorphism' law for Applicative"
quickCheck' 1000 homomorphism
log "Checking 'Interchange' law for Applicative"
quickCheck' 1000 interchange
where
identity ∷ f A → Boolean
identity v = (pure F.identity <*> v) == v
composition ∷ f (B → C) → f (A → B) → f A → Boolean
composition f g x = (pure (<<<) <*> f <*> g <*> x) == (f <*> (g <*> x))
homomorphism ∷ (A → B) → A → Boolean
homomorphism f x = (pure f <*> pure x) == (pure (f x) ∷ f B)
interchange ∷ A → f (A → B) → Boolean
interchange y u = (u <*> pure y) == (pure (_ $ y) <*> u)