CompileNumbers.agda 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. {-# OPTIONS -v treeless.opt:20 #-}
  2. module _ where
  3. open import Agda.Builtin.Nat using (_<_)
  4. open import Common.Prelude
  5. open import Common.Integer
  6. -- Should compile to
  7. -- λ a b → case a of
  8. -- "neg" → 0 - b
  9. -- _ → b
  10. match-on-lit : String → Integer → Integer
  11. match-on-lit "neg" x with x
  12. ... | pos (suc n) = negsuc n
  13. ... | pos 0 = pos 0
  14. ... | negsuc n = pos (suc n)
  15. match-on-lit _ x = x
  16. -- This doesn't compile as nicely, since the match on "neg"
  17. -- ends up between the match on the int and the nat (not sure why).
  18. match-on-lit₂ : String → Integer → Integer
  19. match-on-lit₂ "neg" (pos (suc n)) = negsuc n
  20. match-on-lit₂ "neg" (negsuc n) = pos (suc n)
  21. match-on-lit₂ _ x = x
  22. -- Should compile to a flat case
  23. nested-match : Integer → String
  24. nested-match (pos 0) = "zero"
  25. nested-match (pos 1) = "one"
  26. nested-match (pos (suc (suc n))) = "lots"
  27. nested-match (negsuc 0) = "minus one"
  28. nested-match (negsuc 1) = "minus two"
  29. nested-match (negsuc (suc (suc n))) = "minus lots"
  30. data Diff : Set where
  31. less : Nat → Diff
  32. equal : Diff
  33. greater : Nat → Diff
  34. compareNat : Nat → Nat → Diff
  35. compareNat a b with a < b
  36. ... | true = less (b ∸ suc a)
  37. ... | false with b < a
  38. ... | true = greater (a ∸ suc b)
  39. ... | false = equal
  40. {-# INLINE compareNat #-}
  41. -- Should compile to 0 - a
  42. neg : Nat → Integer
  43. neg zero = pos zero
  44. neg (suc a) = negsuc a
  45. {-# INLINE neg #-}
  46. -- Should compile to a - b
  47. _-N_ : Nat → Nat → Integer
  48. a -N b with compareNat a b
  49. ... | less k = negsuc k
  50. ... | equal = pos (a ∸ b)
  51. ... | greater k = pos (suc k)
  52. {-# INLINE _-N_ #-}
  53. -- Should compile to a + b
  54. _+Z_ : Integer → Integer → Integer
  55. pos a +Z pos b = pos (a + b)
  56. pos a +Z negsuc b = a -N suc b
  57. negsuc a +Z pos b = b -N suc a
  58. negsuc a +Z negsuc b = negsuc (suc a + b)
  59. {-# INLINE _+Z_ #-}
  60. -- Should compile to a * b
  61. _*Z_ : Integer → Integer → Integer
  62. pos a *Z pos b = pos (a * b)
  63. pos a *Z negsuc b = neg (a * suc b)
  64. negsuc a *Z pos b = neg (suc a * b)
  65. negsuc a *Z negsuc b = pos (suc a * suc b)
  66. {-# INLINE _*Z_ #-}
  67. printInt : Integer → IO Unit
  68. printInt x = putStrLn (intToString x)
  69. main : IO Unit
  70. main = printInt (match-on-lit "neg" (pos 42))
  71. ,, printInt (match-on-lit₂ "neg" (pos 42))
  72. ,, putStrLn (nested-match (negsuc 5))