|
| 1 | +------------------------------------------------------------------------ |
| 2 | +-- The Agda standard library |
| 3 | +-- |
| 4 | +-- The Random monad class |
| 5 | +------------------------------------------------------------------------ |
| 6 | + |
| 7 | +{-# OPTIONS --cubical-compatible --guardedness #-} |
| 8 | + |
| 9 | +module Effect.Monad.Random where |
| 10 | + |
| 11 | +open import Algebra using (RawMonoid) |
| 12 | +open import Effect.Functor using (RawFunctor) |
| 13 | +open import Function.Base using (id; const) |
| 14 | +open import IO.Base using (IO) |
| 15 | +open import Level using (Level; _⊔_) |
| 16 | +open import Relation.Binary.Core using (Rel) |
| 17 | + |
| 18 | +open import System.Random as Random using (RandomRIO; InBounds) |
| 19 | + |
| 20 | +private |
| 21 | + variable |
| 22 | + e f g s w : Level |
| 23 | + A : Set f |
| 24 | + B : Set g |
| 25 | + E : Set e |
| 26 | + S : Set s |
| 27 | + R : Rel A f |
| 28 | + M : Set f → Set g |
| 29 | + |
| 30 | +------------------------------------------------------------------------ |
| 31 | +-- Random monad operations |
| 32 | + |
| 33 | +record RawMonadRandom |
| 34 | + (A : Set f) |
| 35 | + (M : Set f → Set g) |
| 36 | + : Set (f ⊔ g) where |
| 37 | + field |
| 38 | + getRandom : M A |
| 39 | + |
| 40 | +record RawMonadRandomR |
| 41 | + (A : Set f) (_≤_ : Rel A f) |
| 42 | + (M : Set f → Set g) |
| 43 | + : Set (f ⊔ g) where |
| 44 | + field |
| 45 | + getRandom : M A |
| 46 | + getRandomR : (lo hi : A) → .(lo≤hi : lo ≤ hi) → M (InBounds _≤_ lo hi) |
| 47 | + |
| 48 | +------------------------------------------------------------------------ |
| 49 | +-- Operations over RawMonadRandom |
| 50 | + |
| 51 | +forgetRanged : RawMonadRandomR A R M → RawMonadRandom A M |
| 52 | +forgetRanged m = record { getRandom = RawMonadRandomR.getRandom m } |
| 53 | + |
| 54 | +------------------------------------------------------------------------ |
| 55 | +-- IO monad specifics |
| 56 | + |
| 57 | +module MkRandomIOInstances |
| 58 | + {a} {A : Set a} (_≤_ : Rel A a) |
| 59 | + (randomIO : IO A) |
| 60 | + (randomRIO : RandomRIO _≤_) where |
| 61 | + |
| 62 | + monadRandomR : RawMonadRandomR A _≤_ IO |
| 63 | + monadRandomR = record |
| 64 | + { getRandom = randomIO |
| 65 | + ; getRandomR = randomRIO } |
| 66 | + |
| 67 | + monadRandom : RawMonadRandom A IO |
| 68 | + monadRandom = forgetRanged monadRandomR |
| 69 | + |
| 70 | +module Char where |
| 71 | + |
| 72 | + open import Data.Char.Base using (Char; _≤_) |
| 73 | + open MkRandomIOInstances _≤_ Random.Char.randomIO Random.Char.randomRIO public |
| 74 | + |
| 75 | +module Float where |
| 76 | + |
| 77 | + open import Data.Float.Base using (Float; _≤_) |
| 78 | + open MkRandomIOInstances _≤_ Random.Float.randomIO Random.Float.randomRIO public |
| 79 | + |
| 80 | +module ℤ where |
| 81 | + |
| 82 | + open import Data.Integer.Base using (ℤ; _≤_) |
| 83 | + open MkRandomIOInstances _≤_ Random.ℤ.randomIO Random.ℤ.randomRIO public |
| 84 | + |
| 85 | +module ℕ where |
| 86 | + |
| 87 | + open import Data.Nat.Base using (ℕ; _≤_) |
| 88 | + open MkRandomIOInstances _≤_ Random.ℕ.randomIO Random.ℕ.randomRIO public |
| 89 | + |
| 90 | +module Word64 where |
| 91 | + |
| 92 | + open import Data.Word64.Base using (Word64; _≤_) |
| 93 | + open MkRandomIOInstances _≤_ Random.Word64.randomIO Random.Word64.randomRIO public |
| 94 | + |
| 95 | +module Fin where |
| 96 | + |
| 97 | + open import Data.Nat.Base using (ℕ; NonZero) |
| 98 | + open import Data.Fin.Base using (Fin; _≤_) |
| 99 | + |
| 100 | + module _ (n : ℕ) .{{p : NonZero n}} where |
| 101 | + open MkRandomIOInstances _≤_ (Random.Fin.randomIO {{p}}) Random.Fin.randomRIO public |
| 102 | + |
| 103 | +module Bool where |
| 104 | + |
| 105 | + open import Data.Bool.Base using (Bool; _≤_) |
| 106 | + open MkRandomIOInstances _≤_ Random.Bool.randomIO Random.Bool.randomRIO public |
| 107 | + |
| 108 | +module List {a} {A : Set a} (rIO : IO A) where |
| 109 | + |
| 110 | + open import Data.List.Base using (List) |
| 111 | + |
| 112 | + monadRandom : RawMonadRandom (List A) IO |
| 113 | + monadRandom = record { getRandom = Random.List.randomIO rIO } |
| 114 | + |
| 115 | + |
| 116 | +open import Data.Nat.Base using (ℕ) |
| 117 | + |
| 118 | +module Vec {a} {A : Set a} (rIO : IO A) (n : ℕ) where |
| 119 | + |
| 120 | + open import Data.Vec.Base using (Vec) |
| 121 | + |
| 122 | + monadRandom : RawMonadRandom (Vec A n) IO |
| 123 | + monadRandom = record { getRandom = Random.Vec.randomIO rIO n } |
| 124 | + |
| 125 | +module Vec≤ {a} {A : Set a} (rIO : IO A) (n : ℕ) where |
| 126 | + |
| 127 | + open import Data.Vec.Bounded.Base using (Vec≤) |
| 128 | + |
| 129 | + monadRandom : RawMonadRandom (Vec≤ A n) IO |
| 130 | + monadRandom = record { getRandom = Random.Vec≤.randomIO rIO n } |
| 131 | + |
| 132 | +module String where |
| 133 | + |
| 134 | + open import Data.String.Base using (String) |
| 135 | + |
| 136 | + monadRandom : RawMonadRandom String IO |
| 137 | + monadRandom = record { getRandom = Random.String.randomIO } |
| 138 | + |
| 139 | +module String≤ (n : ℕ) where |
| 140 | + |
| 141 | + open import Data.String.Base using (String) |
| 142 | + |
| 143 | + monadRandom : RawMonadRandom String IO |
| 144 | + monadRandom = record { getRandom = Random.String≤.randomIO n } |
| 145 | + |
| 146 | +open import Data.Char.Base using (Char; _≤_) |
| 147 | + |
| 148 | +module RangedString≤ (a b : Char) .(a≤b : a ≤ b) (n : ℕ) where |
| 149 | + |
| 150 | + open import Data.String.Base using (String) |
| 151 | + |
| 152 | + monadRandom : RawMonadRandom String IO |
| 153 | + monadRandom = record { getRandom = Random.RangedString≤.randomIO a b a≤b n } |
| 154 | + |
| 155 | +open import Effect.Monad.Reader.Transformer.Base |
| 156 | + |
| 157 | +liftReaderT : RawMonadRandom A M → RawMonadRandom A (ReaderT B M) |
| 158 | +liftReaderT rand = record |
| 159 | + { getRandom = mkReaderT (const Rand.getRandom) |
| 160 | + } where module Rand = RawMonadRandom rand |
| 161 | + |
| 162 | +liftRReaderT : RawMonadRandomR A R M → RawMonadRandomR A R (ReaderT B M) |
| 163 | +liftRReaderT randR = record |
| 164 | + { getRandom = mkReaderT (const RandR.getRandom) |
| 165 | + ; getRandomR = λ lo hi lo≤hi → mkReaderT (const (RandR.getRandomR lo hi lo≤hi)) |
| 166 | + } where module RandR = RawMonadRandomR randR |
| 167 | + |
| 168 | +open import Data.Product.Base using (_,_) |
| 169 | +open import Effect.Monad.Writer.Transformer.Base |
| 170 | + |
| 171 | +module _ {𝕎 : RawMonoid w g} where |
| 172 | + |
| 173 | + open RawMonoid 𝕎 renaming (Carrier to W) |
| 174 | + |
| 175 | + liftWriterT : RawFunctor M → |
| 176 | + RawMonadRandom A M → |
| 177 | + RawMonadRandom A (WriterT 𝕎 M) |
| 178 | + liftWriterT M rand = record |
| 179 | + { getRandom = mkWriterT (λ w → (w ,_) <$> Rand.getRandom) |
| 180 | + } where open RawFunctor M |
| 181 | + module Rand = RawMonadRandom rand |
| 182 | + |
| 183 | + liftRWriterT : RawFunctor M → |
| 184 | + RawMonadRandomR A R M → |
| 185 | + RawMonadRandomR A R (WriterT 𝕎 M) |
| 186 | + liftRWriterT M randR = record |
| 187 | + { getRandom = mkWriterT (λ w → (w ,_) <$> RandR.getRandom) |
| 188 | + ; getRandomR = λ lo hi lo≤hi → mkWriterT (λ w → (w ,_) <$> RandR.getRandomR lo hi lo≤hi) |
| 189 | + } where open RawFunctor M |
| 190 | + module RandR = RawMonadRandomR randR |
| 191 | + |
| 192 | +open import Effect.Monad.State.Transformer.Base |
| 193 | + |
| 194 | +liftStateT : RawFunctor M → |
| 195 | + RawMonadRandom A M → |
| 196 | + RawMonadRandom A (StateT S M) |
| 197 | +liftStateT M rand = record |
| 198 | + { getRandom = mkStateT (λ w → (w ,_) <$> Rand.getRandom) |
| 199 | + } where open RawFunctor M |
| 200 | + module Rand = RawMonadRandom rand |
| 201 | + |
| 202 | +liftRStateT : RawFunctor M → |
| 203 | + RawMonadRandomR A R M → |
| 204 | + RawMonadRandomR A R (StateT S M) |
| 205 | +liftRStateT M randR = record |
| 206 | + { getRandom = mkStateT (λ s → (s ,_) <$> RandR.getRandom) |
| 207 | + ; getRandomR = λ lo hi lo≤hi → mkStateT (λ s → (s ,_) <$> RandR.getRandomR lo hi lo≤hi) |
| 208 | + } where open RawFunctor M |
| 209 | + module RandR = RawMonadRandomR randR |
| 210 | + |
| 211 | + |
| 212 | +open import Data.Sum.Base using (inj₁; inj₂; [_,_]′) |
| 213 | +open import Data.Sum.Effectful.Left.Transformer |
| 214 | + |
| 215 | +liftSumₗT : RawFunctor M → |
| 216 | + RawMonadRandom A M → |
| 217 | + RawMonadRandom A (SumₗT E _ M) |
| 218 | +liftSumₗT M rand = record |
| 219 | + { getRandom = mkSumₗT (inj₂ <$> Rand.getRandom) |
| 220 | + } where open RawFunctor M |
| 221 | + module Rand = RawMonadRandom rand |
| 222 | + |
| 223 | +liftRSumₗT : RawFunctor M → |
| 224 | + RawMonadRandomR A R M → |
| 225 | + RawMonadRandomR A R (SumₗT E _ M) |
| 226 | +liftRSumₗT M randR = record |
| 227 | + { getRandom = mkSumₗT (inj₂ <$> RandR.getRandom) |
| 228 | + ; getRandomR = λ lo hi lo≤hi → mkSumₗT (inj₂ <$> RandR.getRandomR lo hi lo≤hi) |
| 229 | + } where open RawFunctor M |
| 230 | + module RandR = RawMonadRandomR randR |
| 231 | + |
| 232 | +open import Data.Sum.Effectful.Right.Transformer |
| 233 | + |
| 234 | +liftSumᵣT : RawFunctor M → |
| 235 | + RawMonadRandom A M → |
| 236 | + RawMonadRandom A (SumᵣT _ E M) |
| 237 | +liftSumᵣT M rand = record |
| 238 | + { getRandom = mkSumᵣT (inj₁ <$> Rand.getRandom) |
| 239 | + } where open RawFunctor M |
| 240 | + module Rand = RawMonadRandom rand |
| 241 | + |
| 242 | +liftRSumᵣT : RawFunctor M → |
| 243 | + RawMonadRandomR A R M → |
| 244 | + RawMonadRandomR A R (SumᵣT _ E M) |
| 245 | +liftRSumᵣT M randR = record |
| 246 | + { getRandom = mkSumᵣT (inj₁ <$> RandR.getRandom) |
| 247 | + ; getRandomR = λ lo hi lo≤hi → mkSumᵣT (inj₁ <$> RandR.getRandomR lo hi lo≤hi) |
| 248 | + } where open RawFunctor M |
| 249 | + module RandR = RawMonadRandomR randR |
0 commit comments