------------------------------------------------------------------------
-- The Agda standard library
--
-- An effectful view of Delay
------------------------------------------------------------------------

{-# OPTIONS --cubical-compatible --sized-types #-}

module Codata.Sized.Delay.Effectful where

open import Codata.Sized.Delay
  using (Delay; now; never; later; map; bind; zipWith; alignWith)
open import Function.Base using (id)
open import Effect.Choice using (RawChoice)
open import Effect.Empty using (RawEmpty)
open import Effect.Functor using (RawFunctor)
open import Effect.Applicative
  using (RawApplicative; RawApplicativeZero; RawAlternative)
open import Effect.Monad using (RawMonad; RawMonadZero)
open import Data.These using (leftMost)

functor :  {i }  RawFunctor {}  A  Delay A i)
functor = record { _<$>_ = λ f  map f }

module Sequential where

  applicative :  {i }  RawApplicative {}  A  Delay A i)
  applicative = record
    { rawFunctor = functor
    ; pure = now
    ; _<*>_  = λ df da  bind df  f  map f da)
    }

  empty :  {i }  RawEmpty {}  A  Delay A i)
  empty = record { empty = never }

  applicativeZero :  {i }  RawApplicativeZero {}  A  Delay A i)
  applicativeZero = record
    { rawApplicative = applicative
    ; rawEmpty = empty
    }

  monad :  {i }  RawMonad {}  A  Delay A i)
  monad = record
    { rawApplicative = applicative
    ; _>>=_  = bind
    }

  monadZero :  {i }  RawMonadZero {}  A  Delay A i)
  monadZero = record
    { rawMonad = monad
    ; rawEmpty = empty
    }

module Zippy where

  applicative :  {i }  RawApplicative {}  A  Delay A i)
  applicative = record
    { rawFunctor = functor
    ; pure = now
    ; _<*>_  = zipWith id
    }

  empty :  {i }  RawEmpty {}  A  Delay A i)
  empty = record { empty = never }

  applicativeZero :  {i }  RawApplicativeZero {}  A  Delay A i)
  applicativeZero = record
    { rawApplicative = applicative
    ; rawEmpty = empty
    }

  choice :  {i }  RawChoice {}  A  Delay A i)
  choice = record { _<|>_ = alignWith leftMost }

  alternative :  {i }  RawAlternative {}  A  Delay A i)
  alternative = record
    { rawApplicativeZero = applicativeZero
    ; rawChoice = choice
    }