{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

module Profunctor.Monad.Monad where

import qualified Control.Applicative as A
import qualified Control.Monad as M
import qualified Control.Monad.Fail as MF
import Profunctor.Monad.Combinators (with)
import Profunctor.Monad.Core
import Prelude (String)

-- * Rebound syntax

-- $rebindable Works with @RebindableSyntax@.

infixl 1 >>=, >>
infixl 4 <$>, <*>, <*, *>

(<$>)
  :: forall p x a b
  .  ForallF Functor p
  => (a -> b) -> p x a -> p x b
<$> :: (a -> b) -> p x a -> p x b
(<$>) = (Functor (p x) => (a -> b) -> p x a -> p x b)
-> (a -> b) -> p x a -> p x b
forall k2 k1 (cc :: k2 -> Constraint) (p :: k1 -> k2) (x :: k1) a.
ForallF cc p =>
(cc (p x) => a) -> a
with @Functor @p @x Functor (p x) => (a -> b) -> p x a -> p x b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
(A.<$>)

(<*>)
  :: forall p x a b
  .  ForallF Applicative p
  => p x (a -> b) -> p x a -> p x b
<*> :: p x (a -> b) -> p x a -> p x b
(<*>) = (Applicative (p x) => p x (a -> b) -> p x a -> p x b)
-> p x (a -> b) -> p x a -> p x b
forall k2 k1 (cc :: k2 -> Constraint) (p :: k1 -> k2) (x :: k1) a.
ForallF cc p =>
(cc (p x) => a) -> a
with @Applicative @p @x Applicative (p x) => p x (a -> b) -> p x a -> p x b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
(A.<*>)

pure
  :: forall p x a
  .  ForallF Applicative p
  => a -> p x a
pure :: a -> p x a
pure = (Applicative (p x) => a -> p x a) -> a -> p x a
forall k2 k1 (cc :: k2 -> Constraint) (p :: k1 -> k2) (x :: k1) a.
ForallF cc p =>
(cc (p x) => a) -> a
with @Applicative @p @x Applicative (p x) => a -> p x a
forall (f :: * -> *) a. Applicative f => a -> f a
A.pure

(<*)
  :: forall p x a b
  .  ForallF Applicative p
  => p x a -> p x b -> p x a
<* :: p x a -> p x b -> p x a
(<*) = (Applicative (p x) => p x a -> p x b -> p x a)
-> p x a -> p x b -> p x a
forall k2 k1 (cc :: k2 -> Constraint) (p :: k1 -> k2) (x :: k1) a.
ForallF cc p =>
(cc (p x) => a) -> a
with @Applicative @p @x Applicative (p x) => p x a -> p x b -> p x a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
(A.<*)

(*>)
  :: forall p x a b
  .  ForallF Applicative p
  => p x a -> p x b -> p x b
*> :: p x a -> p x b -> p x b
(*>) = (Applicative (p x) => p x a -> p x b -> p x b)
-> p x a -> p x b -> p x b
forall k2 k1 (cc :: k2 -> Constraint) (p :: k1 -> k2) (x :: k1) a.
ForallF cc p =>
(cc (p x) => a) -> a
with @Applicative @p @x Applicative (p x) => p x a -> p x b -> p x b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
(A.*>)

(>>=)
  :: forall p x a b
  .  ForallF Monad p
  => p x a -> (a -> p x b) -> p x b
>>= :: p x a -> (a -> p x b) -> p x b
(>>=) = (Monad (p x) => p x a -> (a -> p x b) -> p x b)
-> p x a -> (a -> p x b) -> p x b
forall k2 k1 (cc :: k2 -> Constraint) (p :: k1 -> k2) (x :: k1) a.
ForallF cc p =>
(cc (p x) => a) -> a
with @Monad @p @x Monad (p x) => p x a -> (a -> p x b) -> p x b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
(M.>>=)

(>>)
  :: forall p x a b
  .  ForallF Monad p
  => p x a -> p x b -> p x b
>> :: p x a -> p x b -> p x b
(>>) = (Monad (p x) => p x a -> p x b -> p x b) -> p x a -> p x b -> p x b
forall k2 k1 (cc :: k2 -> Constraint) (p :: k1 -> k2) (x :: k1) a.
ForallF cc p =>
(cc (p x) => a) -> a
with @Monad @p @x Monad (p x) => p x a -> p x b -> p x b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
(M.>>)

return
  :: forall p x a
  .  ForallF Monad p
  => a -> p x a
return :: a -> p x a
return = (Monad (p x) => a -> p x a) -> a -> p x a
forall k2 k1 (cc :: k2 -> Constraint) (p :: k1 -> k2) (x :: k1) a.
ForallF cc p =>
(cc (p x) => a) -> a
with @Monad @p @x Monad (p x) => a -> p x a
forall (m :: * -> *) a. Monad m => a -> m a
M.return

fail
  :: forall p x a
  .  ForallF MF.MonadFail p
  => String -> p x a
fail :: String -> p x a
fail = (MonadFail (p x) => String -> p x a) -> String -> p x a
forall k2 k1 (cc :: k2 -> Constraint) (p :: k1 -> k2) (x :: k1) a.
ForallF cc p =>
(cc (p x) => a) -> a
with @MF.MonadFail @p @x MonadFail (p x) => String -> p x a
forall (m :: * -> *) a. MonadFail m => String -> m a
MF.fail