{-# LANGUAGE DerivingStrategies #-}

module Data.Comonad.Linear (Comonad (..), ComonadApply (..)) where

import Data.Functor.Linear qualified as Data
import Data.Unrestricted.Linear (Ur (..))

class (Data.Functor w) => Comonad w where
  extract :: w a %1 -> a
  duplicate :: w a %1 -> w (w a)

instance Comonad Ur where
  extract :: forall a. Ur a %1 -> a
extract (Ur a
a) = a
a
  {-# INLINE extract #-}

  duplicate :: forall a. Ur a %1 -> Ur (Ur a)
duplicate (Ur a
a) = Ur a -> Ur (Ur a)
forall a. a -> Ur a
Ur (a -> Ur a
forall a. a -> Ur a
Ur a
a)
  {-# INLINE duplicate #-}

infixl 4 <@>

class (Comonad w) => ComonadApply w where
  (<@>) :: w (a %1 -> b) %1 -> w a %1 -> w b

instance ComonadApply Ur where
  (Ur a %1 -> b
f) <@> :: forall a b. Ur (a %1 -> b) %1 -> Ur a %1 -> Ur b
<@> (Ur a
a) = b -> Ur b
forall a. a -> Ur a
Ur (a %1 -> b
f a
a)
  {-# INLINE (<@>) #-}