-
Notifications
You must be signed in to change notification settings - Fork 0
/
BoolChurch.hs
67 lines (57 loc) · 1.81 KB
/
BoolChurch.hs
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
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE Rank2Types #-}
-- |
-- Module : BoolChurch
-- Copyright : (c) Adrián Enríquez Ballester, 2021
--
-- This module defines a Church encoding
-- for @'Bool'@ values.
module Encoding.BoolChurch
( BoolChurch
, boolChurch
, boolUnchurch
, neg
, conj
, disj
) where
import Encoding (Encoding (from, to))
-- The following pragma avoids HLint hints
-- for simplifying our anonymous functions.
-- In this way we can write more clearly
-- anonymous functions which look like
-- lambda abstractions without HLint complains.
{-# ANN module "HLint: ignore" #-}
-- | The Church encoding type of a @'Bool'@ as
-- an opaque type, just to be seen as a @'Bool'@
-- alternative implementation in terms of polymorphic
-- lambda calculus terms.
newtype BoolChurch = BoolChurch
(forall a. a -> a -> a)
-- | Instance for @'BoolChurch'@ to be an
-- encoding of @'Bool'@ values.
instance Encoding Bool BoolChurch where
from = boolChurch
to = boolUnchurch
-- | Encodes a @'Bool'@ value into its
-- corresponding @'BoolChurch'@.
boolChurch :: Bool -> BoolChurch
boolChurch True = BoolChurch $ \x _ -> x
boolChurch False = BoolChurch $ \_ y -> y
-- | Recovers the @'Bool'@ value from a
-- @'BoolChurch'@.
boolUnchurch :: BoolChurch -> Bool
boolUnchurch (BoolChurch b) = b True False
-- | Logical negation of a @'BoolChurch'@.
neg :: BoolChurch -> BoolChurch
neg (BoolChurch b) =
BoolChurch $ \x y -> b y x
-- | Logical conjunction between @'BoolChurch'@
-- values.
conj :: BoolChurch -> BoolChurch -> BoolChurch
conj (BoolChurch b) (BoolChurch c) =
BoolChurch $ \x y -> b (c x y) y
-- | Logical disjunction between @'BoolChurch'@
-- values.
disj :: BoolChurch -> BoolChurch -> BoolChurch
disj (BoolChurch b) (BoolChurch c) =
BoolChurch $ \x y -> b x (c x y)