module Plutarch.Monadic ((>>=), (>>), fail) where

import Data.String (fromString)
import Plutarch.Internal.Term (
  Config (Tracing),
  Term,
  TracingMode (DetTracing),
  pgetConfig,
 )
import Plutarch.Trace (ptraceInfoError)
import Prelude hiding (fail, (>>), (>>=))

{- | Bind function used within do syntax.

Enables elegant usage of 'pmatch' and similar.
@P.do { y <- x ; z }@ is equivalent to @x $ \y -> z@.

@
  import qualified Plutarch.Monadic as P

  f :: Term s (PTxInfo :--> PBuiltinList (PAsData PTxInInfo))
  f = plam $ \x -> P.do
    PTxInfo txInfoFields <- pmatch x
    pfromData $ pdhead # txInfoFields
@
-}
(>>=) :: (x -> Term s a) -> x -> Term s a
>>= :: forall x (s :: S) (a :: PType). (x -> Term s a) -> x -> Term s a
(>>=) = (x -> Term s a) -> x -> Term s a
forall a. a -> a
id

{- | Forgetful bind function used within do syntax.

Enables elegant usage of 'ptrace' and similar.
@P.do { x ; y }@ is equivalent to @x y@.

@
  import qualified Plutarch.Monadic as P

  P.do
    ptrace "yielding unit"
    pconstant ()
@
-}
(>>) :: (x -> Term s a) -> x -> Term s a
>> :: forall x (s :: S) (a :: PType). (x -> Term s a) -> x -> Term s a
(>>) = (x -> Term s a) -> x -> Term s a
forall a. a -> a
id

{- | Implicitly invoked upon pattern match failure within do syntax.

@
  import qualified Plutarch.Monadic as P

  P.do
    -- calls 'P.fail', traces an error message, and invokes 'perror'.
    PTrue <- pconstant False
@
-}
fail :: String -> Term s a
fail :: forall (s :: S) (a :: PType). String -> Term s a
fail String
s = (Config -> Term s a) -> Term s a
forall (s :: S) (a :: PType). (Config -> Term s a) -> Term s a
pgetConfig ((Config -> Term s a) -> Term s a)
-> (Config -> Term s a) -> Term s a
forall a b. (a -> b) -> a -> b
$ \case
  Tracing LogLevel
_ TracingMode
DetTracing -> Term s PString -> Term s a
forall (a :: PType) (s :: S). Term s PString -> Term s a
ptraceInfoError Term s PString
"Pattern matching failure in QualifiedDo syntax"
  Config
_ -> Term s PString -> Term s a
forall (a :: PType) (s :: S). Term s PString -> Term s a
ptraceInfoError (Term s PString -> Term s a) -> Term s PString -> Term s a
forall a b. (a -> b) -> a -> b
$ String -> Term s PString
forall a. IsString a => String -> a
fromString String
s