------------------------------------------------------------------------
-- 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
open import Function.Base using (id)
open import Effect.Choice
open import Effect.Empty
open import Effect.Functor
open import Effect.Applicative
open import Effect.Monad
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
    }