Syntax.agda 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. {- An agda file contains a single module. The module name should correspond to
  2. the name and path of the file. The path is relative to the project root. In
  3. this case the project root is the root of Agda II. Modules can be
  4. parameterised, but in this case we choose not to parameterise the top-level
  5. module.
  6. -}
  7. module examples.syntax.Syntax where
  8. -- It is recommended that the body of the top-level module is indented by a
  9. -- small amount, but this is not enforced in the syntax.
  10. -- You can have modules inside modules. The name of a sub-module isn't
  11. -- qualified.
  12. module Expressions (X : Set)(x1, x2 : X) where
  13. -- There are three forms of sorts. Set = Set0.
  14. postulate A1 : Set
  15. A2 : Set3
  16. A3 : Prop
  17. -- Independent function space.
  18. fun1 : X -> X
  19. fun1 x = x
  20. -- Implicit independent function space. This is mostly included for
  21. -- symmetry, I can't come up with an example when this would be useful.
  22. fun2 : {X} -> X
  23. fun2 {x} = x
  24. -- Dependent function space.
  25. fun3 : (A:Set) -> A -> A
  26. fun3 A x = x
  27. -- Implicit dependent function space. 'A' is implicit so we don't have to
  28. -- write it out in the function definition.
  29. fun4 : {A:Set} -> A -> A
  30. fun4 x = x
  31. -- You can also write independent functions using the dependent function
  32. -- space syntax. Not that you'd ever want to.
  33. fun5 : (_:X) -> X
  34. fun5 x = x
  35. -- Lambdas can be domain free.
  36. const1 : {A, B : Set} -> A -> B -> A
  37. const1 = \x y -> x
  38. -- Or completely typed.
  39. const2 = \{A:Set}{B:Set}(x:A)(y:B) -> x -- inferable, no type needed
  40. -- You cannot mix typed and untyped arguments in the same lambda.
  41. const3 : {A, B : Set} -> A -> B -> A
  42. const3 = \{A}{B} -> \(x:A)(y:B) -> x
  43. -- You can have wildcards in lambdas
  44. const4 : {A, B : Set} -> A -> B -> A
  45. const4 = \x _ -> x
  46. -- Implicit arguments can be omitted in applications.
  47. x = const1 x1 x2
  48. -- Or made explicit.
  49. x' = const1 {X} {X} x1 x2
  50. -- Infix operators can be bound by lambdas. See ComplexDeclarations for
  51. -- more information about infix operators.
  52. dup : {A:Set} -> (A -> A -> A) -> A -> A
  53. dup = \(+) x -> x + x
  54. -- The two basic declarations are function definitions and datatype
  55. -- declarations.
  56. module BasicDeclarations (X : Set) where
  57. -- The most common declaration is the function definition. It consists of
  58. -- two parts; a type signature and a set of function clauses. Type
  59. -- signatures have the form 'id : type', no telescopes are allowed at this
  60. -- point. This can be discussed.
  61. id : X -> X
  62. id x = x
  63. -- You can omit the type signature if the type can be inferred.
  64. id' = id
  65. -- Datatypes are introduced with the data keyword.
  66. data Bool : Set where
  67. false : Bool
  68. true : Bool
  69. -- The parameters to the datatype (A in this case) are in scope in the
  70. -- types of the constructors. At the moment inductive families are not
  71. -- supported.
  72. data List (A : Set) : Set where
  73. nil : List A
  74. (::) : A -> List A -> List A
  75. -- When using a constructor as a function, the parameters are hidden
  76. -- arguments.
  77. singleton : X -> List X
  78. singleton x = x :: nil
  79. singleton' : X -> List X
  80. singleton' x = (::) {X} x (nil {X})
  81. -- You can pattern match over elements of a datatype when defining
  82. -- functions (and only then).
  83. null : (A : Set) -> List A -> Bool
  84. null A nil = true
  85. null A (x::xs) = false
  86. -- Patterns can be nested (and functions can be recursive).
  87. and : List Bool -> Bool
  88. and nil = true
  89. and (true::xs) = and xs
  90. and (false::xs) = false
  91. -- Functions can be defined in an infix style. When doing this it must be
  92. -- clear what name is being defined without looking at fixities. Hence we
  93. -- could never remove the parenthesis around x::xs in the second clause.
  94. (++) : List X -> List X -> List X
  95. nil ++ ys = ys
  96. (x::xs) ++ ys = x :: (xs ++ ys)
  97. -- You can also use a combination of infix and prefix.
  98. (@) : {A, B, C : Set} -> (B -> C) -> (A -> B) -> A -> C
  99. (f @ g) x = f (g x)
  100. -- Declarations can appear in many different contexts and not all
  101. -- declarations are allowed everywhere.
  102. module ComplexDeclarations (X : Set) where
  103. -- You can introduce new constants with the postulate declaration. A
  104. -- postulate declaration takes a list of type signatures.
  105. postulate A : Set
  106. a : A
  107. -- Let's introduce some datatypes so we have something to work with. At the
  108. -- same time we illustrate that layout is optional.
  109. data Nat : Set where { zero : Nat; suc : Nat -> Nat }
  110. data Bool : Set where { false : Bool; true : Bool }
  111. {- We can declare the fixity of infix symbols. The fixity is tied to a
  112. particular binding of a name. The binding doesn't have to be in scope
  113. directly (as in the example below), but it should be possible to bring
  114. it into scope by moving the fixity declaration further down in the
  115. current block (but never inside things).
  116. The following wouldn't be allowed:
  117. infixl 15 +
  118. mutual
  119. (+) : Nat -> Nat -> Nat
  120. ..
  121. There are three forms: infix, infixl and infixr, for non-associative,
  122. left associative and right associative respectively. The number is the
  123. precedence level.
  124. -}
  125. infixl 15 +, `plus`
  126. (+) : Nat -> Nat -> Nat
  127. n + zero = zero
  128. n + suc m = suc (n + m)
  129. plus = (+)
  130. -- The following code is to stress test the handling of infix applications.
  131. infixl 10 @
  132. infixl 11 @@
  133. infixr 10 #
  134. infixr 11 ##
  135. postulate
  136. (@) : Nat -> Nat -> Nat
  137. (#) : Nat -> Nat -> Nat
  138. (@@) : Nat -> Nat -> Nat
  139. (##) : Nat -> Nat -> Nat
  140. z = zero
  141. test1 = z @ (z # z)
  142. test2 = (z @ z) # z
  143. test3 = z # (z @ z)
  144. test4 = (z # z) @ z
  145. test5 = z ## z # z ## z # z
  146. test6 = z @@ z @ z @@ z @ z
  147. test7 = z # z @@ z @@ z # z
  148. -- Mutually recursive definition are introduced using the 'mutual' keyword.
  149. -- A mutual block can contain function definitions, datatypes
  150. -- (induction-recursion) and fixity declarations.
  151. mutual
  152. even : Nat -> Bool
  153. even zero = true
  154. even (suc n) = odd n
  155. odd : Nat -> Bool
  156. odd zero = false
  157. odd (suc n) = even n
  158. -- If a function is declared abstract the definition of the function is not
  159. -- visible outside the module. For an abstract datatype the constructors
  160. -- are hidden. Definitions that can appear in an abstract block are:
  161. -- function definitions, data declarations, fixity declarations, mutual
  162. -- blocks, open and name space declarations (see NameSpaces).
  163. abstract
  164. data Stack : Set where
  165. nil : Stack
  166. cons : A -> Stack -> Stack
  167. empty : Stack
  168. empty = nil
  169. push : A -> Stack -> Stack
  170. push = cons
  171. -- Local declarations are introduces either with a let or in a where
  172. -- clause. A where clause is attached to a function clause. Everything that
  173. -- can appear in an abstract block can appear in a local declaration, plus
  174. -- abstract blocks. Local functions can be recursive.
  175. foo : (A : Set) -> A -> A
  176. foo A x = let f : Local -> A
  177. f (local y) = y
  178. in f (local x)
  179. where
  180. data Local : Set where
  181. local : A -> Local
  182. -- You can declare things to be private to the current module. This means
  183. -- that they cannot be accessed outside the module (but they're still
  184. -- visible inside the module and its submodules). The only things that
  185. -- cannot appear in a private block are other private blocks and import
  186. -- statements.
  187. private
  188. bar : X -> X
  189. bar x = x
  190. -- Private declarations can go inside mutual and abstract blocks.
  191. mutual
  192. private f : Nat -> Nat
  193. f zero = zero
  194. f (suc n) = g n
  195. g : Nat -> Nat
  196. g n = f n
  197. abstract
  198. Nat' : Set
  199. Nat' = Nat
  200. private h : Nat' -> Nat
  201. h n = n
  202. -- A name space is something that contains names. You can create new
  203. -- name spaces and bring names from a name space into scope.
  204. module NameSpaces where
  205. -- To access definitions from a module in a different file, you have to
  206. -- 'import' this module. Only top-level modules (which have their own
  207. -- files) can be imported.
  208. -- If the imported module is not parameterised a name space with the same
  209. -- name as the module is created.
  210. import examples.syntax.ModuleA
  211. -- We can now refer to things from ModuleA using the created name
  212. -- space. Note that no unqualified names were brought into scope
  213. -- (except, perhaps, the name of the name space). [To bring
  214. -- unqualified names into scope we have to use the 'open'
  215. -- declaration.]
  216. FunnyNat = examples.syntax.ModuleA.Nat
  217. -- If the name of an imported module clashes with a local module we might
  218. -- have to rename the module we are importing
  219. import examples.syntax.ModuleA as A
  220. import examples.syntax.ModuleA as A' using (Nat)
  221. Nat1 = A.Nat
  222. Nat2 = A'.Nat
  223. {- You can't project from a parameterised module. It has to be
  224. instantiated first. The only thing that happens when importing
  225. is that the module name 'examples.syntax.ModuleB' is brought
  226. into scope (and the type checker goes away and type checks this
  227. module).
  228. -}
  229. import examples.syntax.ModuleB
  230. -- To instantiate ModuleB we need something to instantiate it with.
  231. postulate X : Set
  232. (==) : X -> X -> Prop
  233. refl : (x : X) -> x == x
  234. -- To instantiate a module you create a new module and define it as the
  235. -- instantiation in question.
  236. module B = examples.syntax.ModuleB X (==) refl
  237. -- Now the module B contains all the names from ModuleB.
  238. XList = B.List
  239. And = B./\ -- qualified operators are not infix symbols
  240. dummyX = B.SubModule.dummy -- submodules of ModuleB are also in scope
  241. -- This of course works for non-parameterised modules as well.
  242. module B' = B
  243. -- And you can create parameterised modules this way.
  244. module BX ((==) : X -> X -> Prop)(refl : (x : X) -> x == x) = B X (==) refl
  245. -- To bring names from a module into scope you use an open declaration.
  246. open examples.syntax.ModuleA
  247. two : FunnyNat
  248. two = eval (plus (suc zero) (suc zero))
  249. {- In all three declarations (import, module instantiation and open) you
  250. can give modifiers that affect the names which are imported. There are
  251. three modifiers:
  252. using (x1;..;xn) only import x1,..,xn
  253. hiding (x1;..;xn) import everything but x1,..,xn
  254. renaming (x1 to y1;..;xn to yn) import x1,..,xn but call them y1,..,yn
  255. Restrictions:
  256. - a modifier can appear only once
  257. - 'using' and 'hiding' cannot appear together
  258. - imported names must be distinct (e.g. you cannot rename to a name
  259. that is already being imported).
  260. -}
  261. -- B1 only contains True and False
  262. module B1 = B using (True; False)
  263. -- B2 contains True, False and And where And = B./\
  264. module B2 = B using (True; False) renaming (/\ to And)
  265. -- B3 contains everything from B except reflEqList and eqList, plus ===
  266. -- where (===) = B.eqList.
  267. module B3 = B hiding (reflEqList) renaming (eqList to ===)
  268. -- When referring to sub modules you have to be explicitly about it being
  269. -- a module
  270. module B4 = B renaming (module SubModule to Sub)
  271. dummy : X
  272. dummy = B4.Sub.dummy
  273. -- There are two kinds of meta variables; question marks and underscores.
  274. -- Question marks are used for interaction and underscores for implicit
  275. -- arguments.
  276. module MetaVariables where
  277. postulate X : Set
  278. x : X
  279. -- There are two ways of writing a question mark: ? and {! ... !}
  280. -- The type checker will not complain about unsolved question marks (unless
  281. -- you claim you are done).
  282. incomplete : {A:Set} -> A -> A
  283. incomplete x = ?
  284. incomplete' : {A:Set} -> A -> A
  285. incomplete' x = {! you can put anything in here,
  286. even {! nested holes !}
  287. !}
  288. -- Underscores should always be solvable locally. Internally underscores
  289. -- are inserted for implicit arguments, but there are cases where you would
  290. -- like to write them explicitly. For instance, if you want to give one but
  291. -- not all implicit arguments to a function explicitly.
  292. underscore : ({A,B,C:Set} -> (A -> A) -> B -> C) -> X
  293. underscore f = f {_} {X} {_} (\y -> y) x
  294. -- Note that '_' is not an identifier character. The current use of
  295. -- underscore is not the real reason for this. The idea is rather that
  296. -- underscore will be used for subscripts.
  297. id : (A : Set) -> A -> A
  298. id A x = x
  299. x' = id_x -- this means id _ x
  300. -- The parser supports four types of literals. The syntax is the same as in
  301. -- Haskell (since that meant I could steal the lexer for them from ghc).
  302. module Literals where
  303. -- We haven't decided how to handle built-in types.
  304. postulate Integer : Set
  305. Char : Set
  306. String : Set
  307. Float : Set
  308. fortyTwo : Integer
  309. fortyTwo = 42
  310. helloWorld : String
  311. helloWorld = "Hello World!"
  312. escape : Char
  313. escape = '\ESC'
  314. pi : Float
  315. pi = 3.141592
  316. -- There are few things that the parser doesn't implement.
  317. {- Fancy case. I haven't been able to come up with a nice syntax for the
  318. fancy case statement. The difficulty is that we should make it clear
  319. what arguments to the elimination rule will appear as patterns (the
  320. targets). Suggestions are welcome.
  321. Also I'm not sure that we want the fancy case. It would be better to
  322. have a good way of doing actual pattern matching on inductive families.
  323. -}
  324. {- Relative imports. You might want to be able to say
  325. import .ModuleA
  326. to import the module 'current.directory.ModuleA'. Easy to implement but
  327. I'm not sure it's that painful to write the complete name (not a problem
  328. in Haskell for instance). Drawbacks: it looks kind of funny and it adds
  329. an extra bit of syntax to remember.
  330. -}