module Meta.Alt where
record Alt (M : Effect) : Typeω where
  private module M = Effect M
  field
    fail  : βˆ€ {β„“} {A : Type β„“} β†’ M.β‚€ A
    _<|>_ : βˆ€ {β„“} {A : Type β„“} β†’ M.β‚€ A β†’ M.β‚€ A β†’ M.β‚€ A

  infixl 3 _<|>_

open Alt ⦃ ... ⦄ public

guard
  : βˆ€ {M : Effect} (let module M = Effect M) ⦃ appl : Idiom M ⦄ ⦃ alt : Alt M ⦄
  β†’ Bool β†’ M.β‚€ ⊀
guard true = pure tt
guard false = fail

guardM
  : βˆ€ {M : Effect} (let module M = Effect M) ⦃ mon : Bind M ⦄ ⦃ alt : Alt M ⦄
  β†’ M.β‚€ Bool β†’ M.β‚€ ⊀
guardM M = M >>= guard