0 | ||| The content of this module is based on the
1 | ||| tutorial post about [refined primitives](../../Doc/Primitives.md).
9 | --------------------------------------------------------------------------------
10 | -- Elab Scripts
11 | --------------------------------------------------------------------------------
13 | ||| Creates an `Eq` implementation for the given datatype
14 | ||| by using the given accessor function.
15 | |||
16 | ||| This is hardly useful on its own but convenient when
17 | ||| combined with other interface implementors.
18 | |||
19 | ||| In some occasions it is useful to have one or several
20 | ||| phantom types for the refined type. Therefore, the exact
21 | ||| type should be given as a `TTImp`.
22 | |||
23 | ||| ```idris example
24 | ||| record AtomicNr a where
25 | ||| constructor MkAtomicNr
26 | ||| value : Int
27 | ||| 0 inBounds : So (1 <= value && value <= 118)
28 | |||
29 | ||| %runElab refinedEq "AtomicNr" `(AtomicNr a) `{{value}}
30 | ||| ```
31 | export
40 | ]
42 | ||| Creates an `Ord` implementation for the given datatype
43 | ||| by using the given accessor function.
44 | |||
45 | ||| This is hardly useful on its own but convenient when
46 | ||| combined with other interface implementors.
47 | |||
48 | ||| ```idris example
49 | ||| record AtomicNr a where
50 | ||| constructor MkAtomicNr
51 | ||| value : Int
52 | ||| 0 inBounds : So (1 <= value && value <= 118)
53 | |||
54 | ||| %runElab refinedOrd "AtomicNr" `(AtomicNr a) `{{value}}
55 | ||| ```
56 | export
65 | ]
67 | ||| Creates a `Show` implementation for the given datatype
68 | ||| by using the given accessor function.
69 | |||
70 | ||| This is hardly useful on its own but convenient when
71 | ||| combined with other interface implementors.
72 | |||
73 | ||| ```idris example
74 | ||| record AtomicNr a where
75 | ||| constructor MkAtomicNr
76 | ||| value : Int
77 | ||| 0 inBounds : So (1 <= value && value <= 118)
78 | |||
79 | ||| %runElab refinedShow "AtomicNr" `(AtomicNr a) `{{value}}
80 | ||| ```
81 | export
91 | ]
93 | ||| Convenience function combining `refinedEq`, `refinedOrd`,
94 | ||| and `refinedShow`.
95 | export
106 | ||| This creates `Eq`, `Ord`, and `Show` implementations as
107 | ||| well as conversion functions for a refined integral number.
108 | |||
109 | ||| Conversion functions are called `refine` and `fromInteger`
110 | ||| and are put in their own namespace, named after the
111 | ||| data type's name.
112 | |||
113 | ||| ```idris example
114 | ||| record AtomicNr a where
115 | ||| constructor MkAtomicNr
116 | ||| value : Int
117 | ||| 0 inBounds : So (1 <= value && value <= 118)
118 | |||
119 | ||| %runElab refinedIntegral "AtomicNr"
120 | ||| `(AtomicNr a)
121 | ||| `{{MkAtomicNr}}
122 | ||| `{{value}}
123 | ||| `(Int)
124 | ||| ```
125 | |||
126 | ||| The above will result in the following declarations being generated:
127 | |||
128 | ||| ```idris example
129 | ||| Eq AtomicNr where
130 | ||| (==) = (==) `on` value
131 | |||
132 | ||| Ord AtomicNr where
133 | ||| compare = compare `on` value
134 | |||
135 | ||| Show AtomicNr where
136 | ||| showPrec p = showPrec p . value
137 | |||
138 | ||| namespace AtomicNr
139 | ||| refine : Int -> Maybe AtomicNr
140 | ||| refine = refineSo MkAtomicNr
141 | |||
142 | ||| fromInteger :
143 | ||| (v : Integer)
144 | ||| -> {auto 0 _: IsJust (refine $ fromInteger v)}
145 | ||| -> AtomicNr
146 | ||| fromInteger v = fromJust (refine $ fromInteger v)
147 | ||| ```
148 | export
159 | -- this has to be namespaced
160 | -- to avoid disambiguities when being used
161 | -- in fromInteger
165 | declare
177 | ]
178 | ]
180 | export
185 | ||| Specialized version of `refinedIntegral` for data types,
186 | ||| which adhere to the following conventions:
187 | |||
188 | ||| * If a data type's name is `Foo` its constructor is named `MkFoo`.
189 | ||| * The field accessor of the wrapped Int is named `value`.
190 | ||| * The proof of validity consists of a single zero quantity `So`.
191 | |||
192 | ||| ```idris example
193 | ||| record AtomicNr where
194 | ||| constructor MkAtomicNr
195 | ||| value : Int
196 | ||| 0 inBounds : So (1 <= value && value <= 118)
197 | |||
198 | ||| %runElab refinedInt "AtomicNr"
199 | ||| ```
200 | export
204 | ||| Specialized version of `refinedIntegral` for data types,
205 | ||| which adhere to the following conventions:
206 | |||
207 | ||| * If a data type's name is `Foo` its constructor is named `MkFoo`.
208 | ||| * The field accessor of the wrapped Int is named `value`.
209 | ||| * The proof of validity consists of a single zero quantity `So`.
210 | export
214 | ||| Specialized version of `refinedIntegral` for data types,
215 | ||| which adhere to the following conventions:
216 | |||
217 | ||| * If a data type's name is `Foo` its constructor is named `MkFoo`.
218 | ||| * The field accessor of the wrapped Int is named `value`.
219 | ||| * The proof of validity consists of a single zero quantity `So`.
220 | export
224 | ||| Specialized version of `refinedIntegral` for data types,
225 | ||| which adhere to the following conventions:
226 | |||
227 | ||| * If a data type's name is `Foo` its constructor is named `MkFoo`.
228 | ||| * The field accessor of the wrapped Int is named `value`.
229 | ||| * The proof of validity consists of a single zero quantity `So`.
230 | export
234 | ||| Specialized version of `refinedIntegral` for data types,
235 | ||| which adhere to the following conventions:
236 | |||
237 | ||| * If a data type's name is `Foo` its constructor is named `MkFoo`.
238 | ||| * The field accessor of the wrapped Int is named `value`.
239 | ||| * The proof of validity consists of a single zero quantity `So`.
240 | export
244 | ||| Specialized version of `refinedIntegral` for data types,
245 | ||| which adhere to the following conventions:
246 | |||
247 | ||| * If a data type's name is `Foo` its constructor is named `MkFoo`.
248 | ||| * The field accessor of the wrapped Int is named `value`.
249 | ||| * The proof of validity consists of a single zero quantity `So`.
250 | export
254 | ||| Specialized version of `refinedIntegral` for data types,
255 | ||| which adhere to the following conventions:
256 | |||
257 | ||| * If a data type's name is `Foo` its constructor is named `MkFoo`.
258 | ||| * The field accessor of the wrapped Int is named `value`.
259 | ||| * The proof of validity consists of a single zero quantity `So`.
260 | export
264 | ||| Specialized version of `refinedIntegral` for data types,
265 | ||| which adhere to the following conventions:
266 | |||
267 | ||| * If a data type's name is `Foo` its constructor is named `MkFoo`.
268 | ||| * The field accessor of the wrapped Int is named `value`.
269 | ||| * The proof of validity consists of a single zero quantity `So`.
270 | export
274 | ||| Specialized version of `refinedIntegral` for data types,
275 | ||| which adhere to the following conventions:
276 | |||
277 | ||| * If a data type's name is `Foo` its constructor is named `MkFoo`.
278 | ||| * The field accessor of the wrapped Int is named `value`.
279 | ||| * The proof of validity consists of a single zero quantity `So`.
280 | export
284 | ||| This creates `Eq`, `Ord`, and `Show` implementations as
285 | ||| well as conversion functions for a refined floating point
286 | ||| number.
287 | |||
288 | ||| Conversion functions are called `refine` and `fromDouble`
289 | ||| and are put in their own namespace, named after the
290 | ||| data type's name.
291 | |||
292 | ||| ```idris example
293 | ||| record Abundance a where
294 | ||| constructor MkAbundance
295 | ||| value : Double
296 | ||| 0 inBounds : So (0 < value && value <= 1)
297 | |||
298 | ||| %runElab refinedFloating "Abundance" `(Abundance a) `{{MkAbundance}} `{{value}}
299 | ||| ```
300 | |||
301 | ||| The above will result in the following declarations being generated:
302 | |||
303 | ||| ```idris example
304 | ||| Eq Abundance where
305 | ||| (==) = (==) `on` value
306 | |||
307 | ||| Ord Abundance where
308 | ||| compare = compare `on` value
309 | |||
310 | ||| Show Abundance where
311 | ||| showPrec p = showPrec p . value
312 | |||
313 | ||| namespace Abundance
314 | ||| refine : Double -> Maybe Abundance
315 | ||| refine = refineSo MkAbundance
316 | |||
317 | ||| fromDouble : (v : Double)
318 | ||| -> {auto 0 _: IsJust (refine v)}
319 | ||| -> Abundance
320 | ||| fromDouble v = fromJust (refine v)
321 | ||| ```
322 | export
332 | -- this has to be namespaced
333 | -- to avoid disambiguities when being used
334 | -- in fromInteger
338 | declare
350 | ]
351 | ]
353 | ||| Convenience version of `refinedFloating` for data types,
354 | ||| which adhere to the following conventions:
355 | |||
356 | ||| * If a data type's name is `Foo` its constructor is named `MkFoo`.
357 | ||| * The field accessor of the wrapped Int is named `value`.
358 | ||| * The proof of validity consists of a single zero quantity `So`.
359 | export
364 | ||| This creates `Eq`, `Ord`, and `Show` implementations as
365 | ||| well as conversion functions for a refined string value.
366 | |||
367 | ||| Conversion functions are called `refine` and `fromString`
368 | ||| and are put in their own namespace, named after the
369 | ||| data type's name.
370 | |||
371 | ||| ```idris example
372 | ||| record Html a where
373 | ||| constructor MkHtml
374 | ||| value : String
375 | ||| 0 inBounds : So (isValidHtml value)
376 | |||
377 | ||| %runElab refinedText "Html" `(Html a) `{{MkHtml}} `{{value}}
378 | ||| ```
379 | |||
380 | ||| The above will result in the following declarations being generated:
381 | |||
382 | ||| ```idris example
383 | ||| Eq Html where
384 | ||| (==) = (==) `on` value
385 | |||
386 | ||| Ord Html where
387 | ||| compare = compare `on` value
388 | |||
389 | ||| Show Html where
390 | ||| showPrec p = showPrec p . value
391 | |||
392 | ||| namespace Html
393 | ||| refine : String -> Maybe Html
394 | ||| refine = refineSo MkHtml
395 | |||
396 | ||| fromString : (v : String)
397 | ||| -> {auto 0 _: IsJust (refine v)}
398 | ||| -> Html
399 | ||| fromString v = fromJust (refine v)
400 | ||| ```
401 | export
411 | -- this has to be namespaced
412 | -- to avoid disambiguities when being used
413 | -- in fromInteger
417 | declare
429 | ]
430 | ]
432 | ||| Convenience version of `refinedText` for data types,
433 | ||| which adhere to the following conventions:
434 | |||
435 | ||| * If a data type's name is `Foo` its constructor is named `MkFoo`.
436 | ||| * The field accessor of the wrapped Int is named `value`.
437 | ||| * The proof of validity consists of a single zero quantity `So`.
438 | export
442 | ||| This creates `Eq`, `Ord`, and `Show` implementations as
443 | ||| well as conversion functions for a refined charater.
444 | |||
445 | ||| Conversion functions are called `refine` and `fromChar`
446 | ||| and are put in their own namespace, named after the
447 | ||| data type's name.
448 | |||
449 | ||| ```idris example
450 | ||| record Digit a where
451 | ||| constructor MkDigit
452 | ||| value : Char
453 | ||| 0 inBounds : So (isDigit value)
454 | |||
455 | ||| %runElab refinedText "Digit" `(Digit a) `{{MkDigit}} `{{value}}
456 | ||| ```
457 | |||
458 | ||| The above will result in the following declarations being generated:
459 | |||
460 | ||| ```idris example
461 | ||| Eq Digit where
462 | ||| (==) = (==) `on` value
463 | |||
464 | ||| Ord Digit where
465 | ||| compare = compare `on` value
466 | |||
467 | ||| Show Digit where
468 | ||| showPrec p = showPrec p . value
469 | |||
470 | ||| namespace Digit
471 | ||| refine : Char -> Maybe Digit
472 | ||| refine = refineSo MkDigit
473 | |||
474 | ||| fromChar : (v : Char)
475 | ||| -> {auto 0 _: IsJust (refine v)}
476 | ||| -> Digit
477 | ||| fromChar v = fromJust (refine v)
478 | ||| ```
479 | export
489 | -- this has to be namespaced
490 | -- to avoid disambiguities when being used
491 | -- in fromInteger
495 | declare
507 | ]
508 | ]
510 | ||| Convenience version of `refinedCharacter` for data types,
511 | ||| which adhere to the following conventions:
512 | |||
513 | ||| * If a data type's name is `Foo` its constructor is named `MkFoo`.
514 | ||| * The field accessor of the wrapped Char is named `value`.
515 | ||| * The proof of validity consists of a single zero quantity `So`.
516 | export