-
Notifications
You must be signed in to change notification settings - Fork 42
/
Copy pathTest.agda
227 lines (166 loc) · 4.9 KB
/
Test.agda
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
{-# OPTIONS --erase-record-parameters #-}
module _ where
open import Haskell.Prelude
open import Agda.Builtin.Equality
-- ** Foreign HS code
-- language extensions
{-# FOREIGN AGDA2HS
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE FlexibleInstances #-}
#-}
-- imports
{-# FOREIGN AGDA2HS
import Data.Monoid
#-}
-- ** Datatypes & functions
data Exp (v : Set) : Set where
Plus : Exp v → Exp v → Exp v
Lit : Nat → Exp v
Var : v → Exp v
{-# COMPILE AGDA2HS Exp deriving (Show,Eq) #-}
eval : (a → Nat) → Exp a → Nat
eval env (Plus a b) = eval env a + eval env b
eval env (Lit n) = n
eval env (Var x) = env x
{-# COMPILE AGDA2HS eval #-}
-- ** Natural numbers
listSum : List Int → Int
listSum [] = 0
listSum (x ∷ xs) = x + sum xs
{-# COMPILE AGDA2HS listSum #-}
monoSum : List Integer → Integer
monoSum xs = sum xs
{-# COMPILE AGDA2HS monoSum #-}
polySum : ⦃ iNum : Num a ⦄ → List a → a
polySum xs = sum xs
{-# COMPILE AGDA2HS polySum #-}
{-# FOREIGN AGDA2HS
-- comment
-- another comment
bla :: Int -> Int
bla n = n * 4
{- multi
line
comment
-}
#-}
-- ** Extra builtins
ex_float : Double
ex_float = 0.0
{-# COMPILE AGDA2HS ex_float #-}
postulate
toInteger : Word → Integer
ex_word : Word
ex_word = fromInteger 0
{-# COMPILE AGDA2HS ex_word #-}
ex_char : Char
ex_char = 'a'
{-# COMPILE AGDA2HS ex_char #-}
char_d : Char
char_d = toEnum 100
{-# COMPILE AGDA2HS char_d #-}
-- ** Polymorphic functions
_+++_ : List a → List a → List a
[] +++ ys = ys
(x ∷ xs) +++ ys = x ∷ (xs +++ ys)
{-# COMPILE AGDA2HS _+++_ #-}
listMap : (a → b) → List a → List b
listMap f [] = []
listMap f (x ∷ xs) = f x ∷ listMap f xs
{-# COMPILE AGDA2HS listMap #-}
mapTest : List Nat → List Nat
mapTest = map (id ∘ _+_ 5)
{-# COMPILE AGDA2HS mapTest #-}
-- ** Lambdas
plus3 : List Nat → List Nat
plus3 = map (λ n → n + 3)
{-# COMPILE AGDA2HS plus3 #-}
doubleLambda : Nat → Nat → Nat
doubleLambda = λ a b → a + 2 * b
{-# COMPILE AGDA2HS doubleLambda #-}
cnst : a → b → a
cnst = λ x _ → x
{-# COMPILE AGDA2HS cnst #-}
-- ** Constraints
second : (b → c) → a × b → a × c
second f (x , y) = x , f y
{-# COMPILE AGDA2HS second #-}
doubleTake : (n m : Int) → @0 ⦃ IsNonNegativeInt n ⦄ → @0 ⦃ IsNonNegativeInt m ⦄ → List a → List a × List a
doubleTake n m = second (take m) ∘ splitAt n
{-# COMPILE AGDA2HS doubleTake #-}
initLast : (xs : List a) → @0 ⦃ NonEmpty xs ⦄ → List a × a
initLast xs = init xs , last xs
{-# COMPILE AGDA2HS initLast #-}
-- ** Proofs
assoc : (a b c : Nat) → a + (b + c) ≡ (a + b) + c
assoc zero b c = refl
assoc (suc a) b c rewrite assoc a b c = refl
thm : (xs ys : List Nat) → sum (xs ++ ys) ≡ sum xs + sum ys
thm [] ys = refl
thm (x ∷ xs) ys rewrite thm xs ys | assoc x (sum xs) (sum ys) = refl
-- (custom) Monoid class
record MonoidX (a : Set) : Set where
field memptyX : a
mappendX : a → a → a
open MonoidX {{...}} public
{-# COMPILE AGDA2HS MonoidX class #-}
instance
MonoidNat : MonoidX Nat
memptyX {{MonoidNat}} = 0
mappendX {{MonoidNat}} i j = i + j
{-# COMPILE AGDA2HS MonoidNat #-}
instance
MonoidFunNat : MonoidX (a → Nat)
memptyX {{MonoidFunNat}} _ = memptyX
mappendX {{MonoidFunNat}} f g x = mappendX (f x) (g x)
{-# COMPILE AGDA2HS MonoidFunNat #-}
instance
MonoidFun : {{MonoidX b}} → MonoidX (a → b)
memptyX {{MonoidFun}} _ = memptyX
mappendX {{MonoidFun}} f g x = mappendX (f x) (g x)
{-# COMPILE AGDA2HS MonoidFun #-}
sumMonX : {{MonoidX a}} → List a → a
sumMonX [] = memptyX
sumMonX (x ∷ xs) = mappendX x (sumMonX xs)
{-# COMPILE AGDA2HS sumMonX #-}
sumMon : {{Monoid a}} → List a → a
sumMon [] = mempty
sumMon (x ∷ xs) = x <> sumMon xs
{-# COMPILE AGDA2HS sumMon #-}
-- Using the Monoid class from the Prelude
data NatSum : Set where
MkSum : Nat → NatSum
{-# COMPILE AGDA2HS NatSum #-}
instance
SemigroupNatSum : Semigroup NatSum
SemigroupNatSum ._<>_ (MkSum a) (MkSum b) = MkSum (a + b)
MonoidNatSum : Monoid NatSum
MonoidNatSum = record {DefaultMonoid (λ where
.mempty → MkSum 0
)} where open DefaultMonoid
double : ⦃ Monoid a ⦄ → a → a
double x = x <> x
doubleSum : NatSum → NatSum
doubleSum = double
{-# COMPILE AGDA2HS SemigroupNatSum #-}
{-# COMPILE AGDA2HS MonoidNatSum #-}
{-# COMPILE AGDA2HS double #-}
{-# COMPILE AGDA2HS doubleSum #-}
-- Instance argument proof obligation that should not turn into a class constraint
hd : (xs : List a) → @0 ⦃ NonEmpty xs ⦄ → a
hd [] = error "hd: empty list"
hd (x ∷ _) = x
{-# COMPILE AGDA2HS hd #-}
five : Int
five = hd (5 ∷ 3 ∷ [])
{-# COMPILE AGDA2HS five #-}
-- ** Booleans
ex_bool : Bool
ex_bool = True
{-# COMPILE AGDA2HS ex_bool #-}
ex_if : Nat
ex_if = if True then 1 else 0
{-# COMPILE AGDA2HS ex_if #-}
if_over : Nat
if_over = (if True then (λ x → x) else (λ x → x + 1)) 0
{-# COMPILE AGDA2HS if_over #-}