module Meta.Traversable where

Meta: TraversableπŸ”—

The Traverse class captures the idea that some containers β€œcommute with effects”, where an effect is anything implementing Idiom:

record Traversable (F : Effect) : Typeω where
  private module F = Effect F
  field
    traverse
      : βˆ€ {β„“β‚€ ℓ₁} {M : Effect} ⦃ i : Idiom M ⦄ (let module M = Effect M)
          {a : Type β„“β‚€} {b : Type ℓ₁}
      β†’ (a β†’ M.β‚€ b) β†’ F.β‚€ a β†’ M.β‚€ (F.β‚€ b)

  for
    : βˆ€ {β„“β‚€ ℓ₁} {M : Effect} ⦃ i : Idiom M ⦄ (let module M = Effect M)
        {a : Type β„“β‚€} {b : Type ℓ₁}
    β†’ F.β‚€ a β†’ (a β†’ M.β‚€ b) β†’ M.β‚€ (F.β‚€ b)
  for x f = traverse f x

open Traversable ⦃ ... ⦄ public

sequence
  : βˆ€ {M F : Effect} ⦃ _ : Idiom M ⦄ ⦃ _ : Traversable F ⦄
      (let module M = Effect M ; module F = Effect F) {β„“}
      {a : Type β„“}
  β†’ F.β‚€ (M.β‚€ a) β†’ M.β‚€ (F.β‚€ a)
sequence = traverse id