/
Decide.purs
42 lines (34 loc) · 1.26 KB
/
Decide.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
module Data.Decide where
import Prelude
import Data.Comparison (Comparison(..))
import Data.Divide (class Divide)
import Data.Either (Either(..), either)
import Data.Equivalence (Equivalence(..))
import Data.Op (Op(..))
import Data.Predicate (Predicate(..))
-- | `Decide` is the contravariant analogue of `Alt`.
class Divide f <= Decide f where
choose :: forall a b c. (a -> Either b c) -> f b -> f c -> f a
instance chooseComparison :: Decide Comparison where
choose f (Comparison g) (Comparison h) = Comparison \a b -> case f a of
Left c -> case f b of
Left d -> g c d
Right _ -> LT
Right c -> case f b of
Left _ -> GT
Right d -> h c d
instance chooseEquivalence :: Decide Equivalence where
choose f (Equivalence g) (Equivalence h) = Equivalence \a b -> case f a of
Left c -> case f b of
Left d -> g c d
Right _ -> false
Right c -> case f b of
Left _ -> false
Right d -> h c d
instance choosePredicate :: Decide Predicate where
choose f (Predicate g) (Predicate h) = Predicate (either g h <<< f)
instance chooseOp :: Semigroup r => Decide (Op r) where
choose f (Op g) (Op h) = Op (either g h <<< f)
-- | `chosen = choose id`
chosen :: forall f a b. Decide f => f a -> f b -> f (Either a b)
chosen = choose id