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

import Prelude hiding (fail, (>>), (>>=))

import Data.String (fromString)
import Plutarch (pgetConfig, tracingMode, pattern DetTracing)
import Plutarch.Prelude

{- | 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
(>>=) = 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
(>>) = 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 =
  forall (s :: S) (a :: PType). (Config -> Term s a) -> Term s a
pgetConfig \Config
c -> case Config -> TracingMode
tracingMode Config
c of
    TracingMode
DetTracing -> forall (s :: S) (a :: PType). Term s PString -> Term s a
ptraceError Term s PString
"Pattern matching failure in QualifiedDo syntax"
    TracingMode
_ -> forall (s :: S) (a :: PType). Term s PString -> Term s a
ptraceError forall a b. (a -> b) -> a -> b
$ forall a. IsString a => String -> a
fromString String
s