summaryrefslogtreecommitdiff
path: root/src/Encoded/Pair.idr
blob: 42adde5a22cd4f58bc6d67763ad98fd1ba58c7c4 (plain)
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 Encoded.Pair

import Encoded.Bool
import Encoded.Union
import Term.Syntax

export
(*) : Ty -> Ty -> Ty
ty1 * ty2 = B ~> (ty1 <+> ty2)

export
pair : {ty1, ty2 : Ty} -> Term (ty1 ~> ty2 ~> (ty1 * ty2)) ctx
pair = Abs $ Abs $ Abs $
  let t = Var (There $ There Here) in
  let u = Var (There Here) in
  let b = Var Here in
  App if' [<b, App inL [<t], App inR [<u]]

export
fst : {ty1, ty2 : Ty} -> Term ((ty1 * ty2) ~> ty1) ctx
fst = Abs $ App (prL . Var Here) [<True]

export
snd : {ty1, ty2 : Ty} -> Term ((ty1 * ty2) ~> ty2) ctx
snd = Abs $ App (prR . Var Here) [<False]

export
bimap :
  {ty1, ty1', ty2, ty2' : Ty} ->
  Term ((ty1 ~> ty1') ~> (ty2 ~> ty2') ~> ty1 * ty2 ~> ty1' * ty2') ctx
bimap = Abs $ Abs $ Abs $ Abs $
  let f = Var (There $ There $ There Here) in
  let g = Var (There $ There Here) in
  let x = Var (There $ Here) in
  let b = Var Here in
  App if'
    [<b
    , App (inL . f . prL . x) [<True]
    , App (inR . g . prR . x) [<False]
    ]

export
mapSnd : {ty1, ty2, ty2' : Ty} -> Term ((ty2 ~> ty2') ~> ty1 * ty2 ~> ty1 * ty2') ctx
mapSnd = Abs $ Abs $
  let f = Var (There Here) in
  let x = Var Here in
  App pair [<App fst [<x], App (f . snd) [<x]]

export
uncurry : {ty1, ty2, ty : Ty} -> Term ((ty1 ~> ty2 ~> ty) ~> ty1 * ty2 ~> ty) ctx
uncurry = Abs $ Abs $
  let f = Var $ There Here in
  let p = Var Here in
  App f [<App fst [<p], App snd [<p]]