module Data.Maybe.Base where

The Maybe typeπŸ”—

data Maybe {β„“} (A : Type β„“) : Type β„“ where
  nothing : Maybe A
  just    : A β†’ Maybe A

{-# BUILTIN MAYBE Maybe #-}
instance
  Map-Maybe : Map (eff Maybe)
  Map-Maybe .map f (just x) = just (f x)
  Map-Maybe .map f nothing  = nothing

  Idiom-Maybe : Idiom (eff Maybe)
  Idiom-Maybe .Idiom.Map-idiom = Map-Maybe

  Idiom-Maybe .Idiom.pure  = just

  Idiom-Maybe .Idiom._<*>_ (just f) (just x) = just (f x)
  Idiom-Maybe .Idiom._<*>_ (just f) nothing  = nothing
  Idiom-Maybe .Idiom._<*>_ nothing  _        = nothing

  Bind-Maybe : Bind (eff Maybe)
  Bind-Maybe .Bind.Idiom-bind = Idiom-Maybe

  Bind-Maybe ._>>=_ (just x) f = f x
  Bind-Maybe ._>>=_ nothing  f = nothing

  Alt-Maybe : Alt (eff Maybe)
  Alt-Maybe .Alt.fail = nothing
  Alt-Maybe .Alt._<|>_ (just x) y = just x
  Alt-Maybe .Alt._<|>_ nothing y = y

  Traversable-Maybe : Traversable (eff Maybe)
  Traversable-Maybe .Traversable.traverse f nothing  = pure nothing
  Traversable-Maybe .Traversable.traverse f (just x) = just <$> f x

Maybe-rec : (A β†’ B) β†’ B β†’ Maybe A β†’ B
Maybe-rec f b (just x) = f x
Maybe-rec f b nothing = b
from-just : A β†’ Maybe A β†’ A
from-just def (just x) = x
from-just def nothing = def

Pointed types as Maybe-algebrasπŸ”—

maybeβ†’alt : βˆ€ {M : Effect} {β„“} {A : Type β„“}
          β†’ ⦃ _ : Alt M ⦄ ⦃ _ : Idiom M ⦄ β†’ Maybe A β†’ M .Effect.β‚€ A
maybe→alt (just x) = pure x
maybe→alt nothing  = fail