{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds           #-}
{-# LANGUAGE DeriveAnyClass      #-}
{-# LANGUAGE DeriveFunctor       #-}
{-# LANGUAGE DeriveGeneric       #-}
{-# LANGUAGE DerivingStrategies  #-}
{-# LANGUAGE DerivingVia         #-}
{-# LANGUAGE FlexibleContexts    #-}
{-# LANGUAGE GADTs               #-}
{-# LANGUAGE KindSignatures      #-}
{-# LANGUAGE LambdaCase          #-}
{-# LANGUAGE MonoLocalBinds      #-}
{-# LANGUAGE NamedFieldPuns      #-}
{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE RankNTypes          #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell     #-}
{-# LANGUAGE TupleSections       #-}
{-# LANGUAGE TypeApplications    #-}
{-# LANGUAGE TypeOperators       #-}
{-
This module defines the 'Resumable' effect and its handlers.

@Resumable i o@ programs work like state machines. Their state type is
'Requests' @o@ and their input type is 'Response' @i@. Note that the state
contains multiple requests, but the input only has a single response.
See note [Resumable state machine] for details.

== Constructing resumable programs
Resumable programs can be constructed using 'prompt' and 'select'. 'prompt'
has one argument that describes the request.

>>> (prompt "A") 'select' (prompt "B")

makes two requests and returns the answer of the one that is responded to
first. In the state machine analogy, the initial state of this program would
be the set of the two requests @"A"@ and @"B"@.

== Running resumable programs
The 'Resumable' effect is handled in two stages, using 'handleResumable' and
'handleNonDetPrompt' (see note [Running resumable programs] for a description
of how it works). The types 'Requests' and 'Responses' store the requests
made by, and responses given to, a resumable program.

== 'Resumable' and non-determinism
The kind of non-determinism used in 'Resumable' is different from the kind
encoded in 'Control.Applicative.Alternative' in that it does not allow
for backtracking (because it's not meant to encode "searching a problem
space for a solution"). 'Resumable' programs do not have the ability to call
'Control.Applicative.Alternative.empty' and therefore do not implement
the 'Control.Applicative.Alternative' class.

-}
module Plutus.Contract.Resumable(
    -- * The 'Resumable' effect
    Resumable(..)
    , prompt
    , select
    , never
    -- * Handling the 'Resumable' effect
    , Request(..)
    , Response(..)
    , RequestID(..)
    , IterationID(..)
    , Requests(..)
    , ResumableEffs
    , Responses(..)
    , insertResponse
    , responses
    , _Responses
    -- * Handling the 'Resumable' effect with continuations
    , handleResumable
    , suspendNonDet
    , MultiRequestContStatus(..)
    , MultiRequestContinuation(..)
    , ReqMap(..)
    ) where

import Control.Applicative
import Control.Lens (Iso', iso)
import Data.Aeson (FromJSON, FromJSONKey, ToJSON, ToJSONKey)
import Data.Map (Map)
import Data.Map qualified as Map
import Data.Semigroup (Max (..))
import GHC.Generics (Generic)
import Numeric.Natural (Natural)
import Prettyprinter

import Control.Monad.Freer
import Control.Monad.Freer.Coroutine
import Control.Monad.Freer.NonDet
import Control.Monad.Freer.State

{- Note [Resumable state machine]

@Resumable i o@ programs are like state machines with state 'Requests' @o@ and
input 'Response' @i@. So instead of using the 'Resumable' effect we could also
write

@
    data SM i o effs = SM { currentState :: Requests o, transition :: Response i -> Eff effs (Maybe (Either a (SM i o effs)))
@

using 'Maybe' to denote the failure state and 'Either a' for the final state of
type @a@.

And this is indeed almost exactly the definition 'MultiRequestContinuation'.

We can transform an @Eff (Resumable i o ': effs)@ program into an
@Eff effs (Maybe (MultiRequestContStatus i o effs a))@ using 'handleResumable'
and 'suspendNonDet'.

-}

-- | A data type for representing non-deterministic prompts.
data Resumable i o r where
    RRequest :: o -> Resumable i o i

    -- See https://hackage.haskell.org/package/freer-simple-1.2.1.1/docs/src/Control.Monad.Freer.Internal.html#NonDet
    RSelect :: Resumable i o Bool
    RZero   :: Resumable i o a

prompt :: Member (Resumable i o) effs => o -> Eff effs i
prompt :: o -> Eff effs i
prompt o
o = Resumable i o i -> Eff effs i
forall (eff :: * -> *) (effs :: [* -> *]) a.
Member eff effs =>
eff a -> Eff effs a
send (o -> Resumable i o i
forall o i. o -> Resumable i o i
RRequest o
o)

select ::
    forall i o effs a.
    Member (Resumable i o) effs
    => Eff effs a
    -> Eff effs a
    -> Eff effs a
select :: Eff effs a -> Eff effs a -> Eff effs a
select Eff effs a
l Eff effs a
r = Resumable i o Bool -> Eff effs Bool
forall (eff :: * -> *) (effs :: [* -> *]) a.
Member eff effs =>
eff a -> Eff effs a
send @(Resumable i o) Resumable i o Bool
forall i o. Resumable i o Bool
RSelect Eff effs Bool -> (Bool -> Eff effs a) -> Eff effs a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Bool
b -> if Bool
b then Eff effs a
l else Eff effs a
r

never ::
    forall i o effs a.
    Member (Resumable i o) effs
    => Eff effs a
never :: Eff effs a
never = Resumable i o a -> Eff effs a
forall (eff :: * -> *) (effs :: [* -> *]) a.
Member eff effs =>
eff a -> Eff effs a
send @(Resumable i o) Resumable i o a
forall i o a. Resumable i o a
RZero

-- | A value that uniquely identifies requests made during the execution of
--   'Resumable' programs.
newtype RequestID = RequestID Natural
    deriving stock (RequestID -> RequestID -> Bool
(RequestID -> RequestID -> Bool)
-> (RequestID -> RequestID -> Bool) -> Eq RequestID
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RequestID -> RequestID -> Bool
$c/= :: RequestID -> RequestID -> Bool
== :: RequestID -> RequestID -> Bool
$c== :: RequestID -> RequestID -> Bool
Eq, Eq RequestID
Eq RequestID
-> (RequestID -> RequestID -> Ordering)
-> (RequestID -> RequestID -> Bool)
-> (RequestID -> RequestID -> Bool)
-> (RequestID -> RequestID -> Bool)
-> (RequestID -> RequestID -> Bool)
-> (RequestID -> RequestID -> RequestID)
-> (RequestID -> RequestID -> RequestID)
-> Ord RequestID
RequestID -> RequestID -> Bool
RequestID -> RequestID -> Ordering
RequestID -> RequestID -> RequestID
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: RequestID -> RequestID -> RequestID
$cmin :: RequestID -> RequestID -> RequestID
max :: RequestID -> RequestID -> RequestID
$cmax :: RequestID -> RequestID -> RequestID
>= :: RequestID -> RequestID -> Bool
$c>= :: RequestID -> RequestID -> Bool
> :: RequestID -> RequestID -> Bool
$c> :: RequestID -> RequestID -> Bool
<= :: RequestID -> RequestID -> Bool
$c<= :: RequestID -> RequestID -> Bool
< :: RequestID -> RequestID -> Bool
$c< :: RequestID -> RequestID -> Bool
compare :: RequestID -> RequestID -> Ordering
$ccompare :: RequestID -> RequestID -> Ordering
$cp1Ord :: Eq RequestID
Ord, Int -> RequestID -> ShowS
[RequestID] -> ShowS
RequestID -> String
(Int -> RequestID -> ShowS)
-> (RequestID -> String)
-> ([RequestID] -> ShowS)
-> Show RequestID
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RequestID] -> ShowS
$cshowList :: [RequestID] -> ShowS
show :: RequestID -> String
$cshow :: RequestID -> String
showsPrec :: Int -> RequestID -> ShowS
$cshowsPrec :: Int -> RequestID -> ShowS
Show, (forall x. RequestID -> Rep RequestID x)
-> (forall x. Rep RequestID x -> RequestID) -> Generic RequestID
forall x. Rep RequestID x -> RequestID
forall x. RequestID -> Rep RequestID x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep RequestID x -> RequestID
$cfrom :: forall x. RequestID -> Rep RequestID x
Generic)
    deriving newtype ([RequestID] -> Encoding
[RequestID] -> Value
RequestID -> Encoding
RequestID -> Value
(RequestID -> Value)
-> (RequestID -> Encoding)
-> ([RequestID] -> Value)
-> ([RequestID] -> Encoding)
-> ToJSON RequestID
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [RequestID] -> Encoding
$ctoEncodingList :: [RequestID] -> Encoding
toJSONList :: [RequestID] -> Value
$ctoJSONList :: [RequestID] -> Value
toEncoding :: RequestID -> Encoding
$ctoEncoding :: RequestID -> Encoding
toJSON :: RequestID -> Value
$ctoJSON :: RequestID -> Value
ToJSON, Value -> Parser [RequestID]
Value -> Parser RequestID
(Value -> Parser RequestID)
-> (Value -> Parser [RequestID]) -> FromJSON RequestID
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [RequestID]
$cparseJSONList :: Value -> Parser [RequestID]
parseJSON :: Value -> Parser RequestID
$cparseJSON :: Value -> Parser RequestID
FromJSON, ToJSONKeyFunction [RequestID]
ToJSONKeyFunction RequestID
ToJSONKeyFunction RequestID
-> ToJSONKeyFunction [RequestID] -> ToJSONKey RequestID
forall a.
ToJSONKeyFunction a -> ToJSONKeyFunction [a] -> ToJSONKey a
toJSONKeyList :: ToJSONKeyFunction [RequestID]
$ctoJSONKeyList :: ToJSONKeyFunction [RequestID]
toJSONKey :: ToJSONKeyFunction RequestID
$ctoJSONKey :: ToJSONKeyFunction RequestID
ToJSONKey, FromJSONKeyFunction [RequestID]
FromJSONKeyFunction RequestID
FromJSONKeyFunction RequestID
-> FromJSONKeyFunction [RequestID] -> FromJSONKey RequestID
forall a.
FromJSONKeyFunction a -> FromJSONKeyFunction [a] -> FromJSONKey a
fromJSONKeyList :: FromJSONKeyFunction [RequestID]
$cfromJSONKeyList :: FromJSONKeyFunction [RequestID]
fromJSONKey :: FromJSONKeyFunction RequestID
$cfromJSONKey :: FromJSONKeyFunction RequestID
FromJSONKey, [RequestID] -> Doc ann
RequestID -> Doc ann
(forall ann. RequestID -> Doc ann)
-> (forall ann. [RequestID] -> Doc ann) -> Pretty RequestID
forall ann. [RequestID] -> Doc ann
forall ann. RequestID -> Doc ann
forall a.
(forall ann. a -> Doc ann)
-> (forall ann. [a] -> Doc ann) -> Pretty a
prettyList :: [RequestID] -> Doc ann
$cprettyList :: forall ann. [RequestID] -> Doc ann
pretty :: RequestID -> Doc ann
$cpretty :: forall ann. RequestID -> Doc ann
Pretty, Int -> RequestID
RequestID -> Int
RequestID -> [RequestID]
RequestID -> RequestID
RequestID -> RequestID -> [RequestID]
RequestID -> RequestID -> RequestID -> [RequestID]
(RequestID -> RequestID)
-> (RequestID -> RequestID)
-> (Int -> RequestID)
-> (RequestID -> Int)
-> (RequestID -> [RequestID])
-> (RequestID -> RequestID -> [RequestID])
-> (RequestID -> RequestID -> [RequestID])
-> (RequestID -> RequestID -> RequestID -> [RequestID])
-> Enum RequestID
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: RequestID -> RequestID -> RequestID -> [RequestID]
$cenumFromThenTo :: RequestID -> RequestID -> RequestID -> [RequestID]
enumFromTo :: RequestID -> RequestID -> [RequestID]
$cenumFromTo :: RequestID -> RequestID -> [RequestID]
enumFromThen :: RequestID -> RequestID -> [RequestID]
$cenumFromThen :: RequestID -> RequestID -> [RequestID]
enumFrom :: RequestID -> [RequestID]
$cenumFrom :: RequestID -> [RequestID]
fromEnum :: RequestID -> Int
$cfromEnum :: RequestID -> Int
toEnum :: Int -> RequestID
$ctoEnum :: Int -> RequestID
pred :: RequestID -> RequestID
$cpred :: RequestID -> RequestID
succ :: RequestID -> RequestID
$csucc :: RequestID -> RequestID
Enum, Integer -> RequestID
RequestID -> RequestID
RequestID -> RequestID -> RequestID
(RequestID -> RequestID -> RequestID)
-> (RequestID -> RequestID -> RequestID)
-> (RequestID -> RequestID -> RequestID)
-> (RequestID -> RequestID)
-> (RequestID -> RequestID)
-> (RequestID -> RequestID)
-> (Integer -> RequestID)
-> Num RequestID
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> RequestID
$cfromInteger :: Integer -> RequestID
signum :: RequestID -> RequestID
$csignum :: RequestID -> RequestID
abs :: RequestID -> RequestID
$cabs :: RequestID -> RequestID
negate :: RequestID -> RequestID
$cnegate :: RequestID -> RequestID
* :: RequestID -> RequestID -> RequestID
$c* :: RequestID -> RequestID -> RequestID
- :: RequestID -> RequestID -> RequestID
$c- :: RequestID -> RequestID -> RequestID
+ :: RequestID -> RequestID -> RequestID
$c+ :: RequestID -> RequestID -> RequestID
Num)

-- | A value that uniquely identifies groups of requests.
newtype IterationID = IterationID Natural
    deriving stock (IterationID -> IterationID -> Bool
(IterationID -> IterationID -> Bool)
-> (IterationID -> IterationID -> Bool) -> Eq IterationID
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: IterationID -> IterationID -> Bool
$c/= :: IterationID -> IterationID -> Bool
== :: IterationID -> IterationID -> Bool
$c== :: IterationID -> IterationID -> Bool
Eq, Eq IterationID
Eq IterationID
-> (IterationID -> IterationID -> Ordering)
-> (IterationID -> IterationID -> Bool)
-> (IterationID -> IterationID -> Bool)
-> (IterationID -> IterationID -> Bool)
-> (IterationID -> IterationID -> Bool)
-> (IterationID -> IterationID -> IterationID)
-> (IterationID -> IterationID -> IterationID)
-> Ord IterationID
IterationID -> IterationID -> Bool
IterationID -> IterationID -> Ordering
IterationID -> IterationID -> IterationID
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: IterationID -> IterationID -> IterationID
$cmin :: IterationID -> IterationID -> IterationID
max :: IterationID -> IterationID -> IterationID
$cmax :: IterationID -> IterationID -> IterationID
>= :: IterationID -> IterationID -> Bool
$c>= :: IterationID -> IterationID -> Bool
> :: IterationID -> IterationID -> Bool
$c> :: IterationID -> IterationID -> Bool
<= :: IterationID -> IterationID -> Bool
$c<= :: IterationID -> IterationID -> Bool
< :: IterationID -> IterationID -> Bool
$c< :: IterationID -> IterationID -> Bool
compare :: IterationID -> IterationID -> Ordering
$ccompare :: IterationID -> IterationID -> Ordering
$cp1Ord :: Eq IterationID
Ord, Int -> IterationID -> ShowS
[IterationID] -> ShowS
IterationID -> String
(Int -> IterationID -> ShowS)
-> (IterationID -> String)
-> ([IterationID] -> ShowS)
-> Show IterationID
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [IterationID] -> ShowS
$cshowList :: [IterationID] -> ShowS
show :: IterationID -> String
$cshow :: IterationID -> String
showsPrec :: Int -> IterationID -> ShowS
$cshowsPrec :: Int -> IterationID -> ShowS
Show, (forall x. IterationID -> Rep IterationID x)
-> (forall x. Rep IterationID x -> IterationID)
-> Generic IterationID
forall x. Rep IterationID x -> IterationID
forall x. IterationID -> Rep IterationID x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep IterationID x -> IterationID
$cfrom :: forall x. IterationID -> Rep IterationID x
Generic)
    deriving newtype ([IterationID] -> Encoding
[IterationID] -> Value
IterationID -> Encoding
IterationID -> Value
(IterationID -> Value)
-> (IterationID -> Encoding)
-> ([IterationID] -> Value)
-> ([IterationID] -> Encoding)
-> ToJSON IterationID
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [IterationID] -> Encoding
$ctoEncodingList :: [IterationID] -> Encoding
toJSONList :: [IterationID] -> Value
$ctoJSONList :: [IterationID] -> Value
toEncoding :: IterationID -> Encoding
$ctoEncoding :: IterationID -> Encoding
toJSON :: IterationID -> Value
$ctoJSON :: IterationID -> Value
ToJSON, Value -> Parser [IterationID]
Value -> Parser IterationID
(Value -> Parser IterationID)
-> (Value -> Parser [IterationID]) -> FromJSON IterationID
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [IterationID]
$cparseJSONList :: Value -> Parser [IterationID]
parseJSON :: Value -> Parser IterationID
$cparseJSON :: Value -> Parser IterationID
FromJSON, ToJSONKeyFunction [IterationID]
ToJSONKeyFunction IterationID
ToJSONKeyFunction IterationID
-> ToJSONKeyFunction [IterationID] -> ToJSONKey IterationID
forall a.
ToJSONKeyFunction a -> ToJSONKeyFunction [a] -> ToJSONKey a
toJSONKeyList :: ToJSONKeyFunction [IterationID]
$ctoJSONKeyList :: ToJSONKeyFunction [IterationID]
toJSONKey :: ToJSONKeyFunction IterationID
$ctoJSONKey :: ToJSONKeyFunction IterationID
ToJSONKey, FromJSONKeyFunction [IterationID]
FromJSONKeyFunction IterationID
FromJSONKeyFunction IterationID
-> FromJSONKeyFunction [IterationID] -> FromJSONKey IterationID
forall a.
FromJSONKeyFunction a -> FromJSONKeyFunction [a] -> FromJSONKey a
fromJSONKeyList :: FromJSONKeyFunction [IterationID]
$cfromJSONKeyList :: FromJSONKeyFunction [IterationID]
fromJSONKey :: FromJSONKeyFunction IterationID
$cfromJSONKey :: FromJSONKeyFunction IterationID
FromJSONKey, [IterationID] -> Doc ann
IterationID -> Doc ann
(forall ann. IterationID -> Doc ann)
-> (forall ann. [IterationID] -> Doc ann) -> Pretty IterationID
forall ann. [IterationID] -> Doc ann
forall ann. IterationID -> Doc ann
forall a.
(forall ann. a -> Doc ann)
-> (forall ann. [a] -> Doc ann) -> Pretty a
prettyList :: [IterationID] -> Doc ann
$cprettyList :: forall ann. [IterationID] -> Doc ann
pretty :: IterationID -> Doc ann
$cpretty :: forall ann. IterationID -> Doc ann
Pretty, Int -> IterationID
IterationID -> Int
IterationID -> [IterationID]
IterationID -> IterationID
IterationID -> IterationID -> [IterationID]
IterationID -> IterationID -> IterationID -> [IterationID]
(IterationID -> IterationID)
-> (IterationID -> IterationID)
-> (Int -> IterationID)
-> (IterationID -> Int)
-> (IterationID -> [IterationID])
-> (IterationID -> IterationID -> [IterationID])
-> (IterationID -> IterationID -> [IterationID])
-> (IterationID -> IterationID -> IterationID -> [IterationID])
-> Enum IterationID
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: IterationID -> IterationID -> IterationID -> [IterationID]
$cenumFromThenTo :: IterationID -> IterationID -> IterationID -> [IterationID]
enumFromTo :: IterationID -> IterationID -> [IterationID]
$cenumFromTo :: IterationID -> IterationID -> [IterationID]
enumFromThen :: IterationID -> IterationID -> [IterationID]
$cenumFromThen :: IterationID -> IterationID -> [IterationID]
enumFrom :: IterationID -> [IterationID]
$cenumFrom :: IterationID -> [IterationID]
fromEnum :: IterationID -> Int
$cfromEnum :: IterationID -> Int
toEnum :: Int -> IterationID
$ctoEnum :: Int -> IterationID
pred :: IterationID -> IterationID
$cpred :: IterationID -> IterationID
succ :: IterationID -> IterationID
$csucc :: IterationID -> IterationID
Enum, Integer -> IterationID
IterationID -> IterationID
IterationID -> IterationID -> IterationID
(IterationID -> IterationID -> IterationID)
-> (IterationID -> IterationID -> IterationID)
-> (IterationID -> IterationID -> IterationID)
-> (IterationID -> IterationID)
-> (IterationID -> IterationID)
-> (IterationID -> IterationID)
-> (Integer -> IterationID)
-> Num IterationID
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> IterationID
$cfromInteger :: Integer -> IterationID
signum :: IterationID -> IterationID
$csignum :: IterationID -> IterationID
abs :: IterationID -> IterationID
$cabs :: IterationID -> IterationID
negate :: IterationID -> IterationID
$cnegate :: IterationID -> IterationID
* :: IterationID -> IterationID -> IterationID
$c* :: IterationID -> IterationID -> IterationID
- :: IterationID -> IterationID -> IterationID
$c- :: IterationID -> IterationID -> IterationID
+ :: IterationID -> IterationID -> IterationID
$c+ :: IterationID -> IterationID -> IterationID
Num)
    deriving (b -> IterationID -> IterationID
NonEmpty IterationID -> IterationID
IterationID -> IterationID -> IterationID
(IterationID -> IterationID -> IterationID)
-> (NonEmpty IterationID -> IterationID)
-> (forall b. Integral b => b -> IterationID -> IterationID)
-> Semigroup IterationID
forall b. Integral b => b -> IterationID -> IterationID
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
stimes :: b -> IterationID -> IterationID
$cstimes :: forall b. Integral b => b -> IterationID -> IterationID
sconcat :: NonEmpty IterationID -> IterationID
$csconcat :: NonEmpty IterationID -> IterationID
<> :: IterationID -> IterationID -> IterationID
$c<> :: IterationID -> IterationID -> IterationID
Semigroup) via (Max Natural)

instance Monoid IterationID where
    mappend :: IterationID -> IterationID -> IterationID
mappend = IterationID -> IterationID -> IterationID
forall a. Semigroup a => a -> a -> a
(<>)
    mempty :: IterationID
mempty = Natural -> IterationID
IterationID Natural
0

data Request o =
    Request
        { Request o -> RequestID
rqID      :: RequestID
        , Request o -> IterationID
itID      :: IterationID
        , Request o -> o
rqRequest :: o
        } deriving stock (Request o -> Request o -> Bool
(Request o -> Request o -> Bool)
-> (Request o -> Request o -> Bool) -> Eq (Request o)
forall o. Eq o => Request o -> Request o -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Request o -> Request o -> Bool
$c/= :: forall o. Eq o => Request o -> Request o -> Bool
== :: Request o -> Request o -> Bool
$c== :: forall o. Eq o => Request o -> Request o -> Bool
Eq, Eq (Request o)
Eq (Request o)
-> (Request o -> Request o -> Ordering)
-> (Request o -> Request o -> Bool)
-> (Request o -> Request o -> Bool)
-> (Request o -> Request o -> Bool)
-> (Request o -> Request o -> Bool)
-> (Request o -> Request o -> Request o)
-> (Request o -> Request o -> Request o)
-> Ord (Request o)
Request o -> Request o -> Bool
Request o -> Request o -> Ordering
Request o -> Request o -> Request o
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall o. Ord o => Eq (Request o)
forall o. Ord o => Request o -> Request o -> Bool
forall o. Ord o => Request o -> Request o -> Ordering
forall o. Ord o => Request o -> Request o -> Request o
min :: Request o -> Request o -> Request o
$cmin :: forall o. Ord o => Request o -> Request o -> Request o
max :: Request o -> Request o -> Request o
$cmax :: forall o. Ord o => Request o -> Request o -> Request o
>= :: Request o -> Request o -> Bool
$c>= :: forall o. Ord o => Request o -> Request o -> Bool
> :: Request o -> Request o -> Bool
$c> :: forall o. Ord o => Request o -> Request o -> Bool
<= :: Request o -> Request o -> Bool
$c<= :: forall o. Ord o => Request o -> Request o -> Bool
< :: Request o -> Request o -> Bool
$c< :: forall o. Ord o => Request o -> Request o -> Bool
compare :: Request o -> Request o -> Ordering
$ccompare :: forall o. Ord o => Request o -> Request o -> Ordering
$cp1Ord :: forall o. Ord o => Eq (Request o)
Ord, Int -> Request o -> ShowS
[Request o] -> ShowS
Request o -> String
(Int -> Request o -> ShowS)
-> (Request o -> String)
-> ([Request o] -> ShowS)
-> Show (Request o)
forall o. Show o => Int -> Request o -> ShowS
forall o. Show o => [Request o] -> ShowS
forall o. Show o => Request o -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Request o] -> ShowS
$cshowList :: forall o. Show o => [Request o] -> ShowS
show :: Request o -> String
$cshow :: forall o. Show o => Request o -> String
showsPrec :: Int -> Request o -> ShowS
$cshowsPrec :: forall o. Show o => Int -> Request o -> ShowS
Show, (forall x. Request o -> Rep (Request o) x)
-> (forall x. Rep (Request o) x -> Request o)
-> Generic (Request o)
forall x. Rep (Request o) x -> Request o
forall x. Request o -> Rep (Request o) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall o x. Rep (Request o) x -> Request o
forall o x. Request o -> Rep (Request o) x
$cto :: forall o x. Rep (Request o) x -> Request o
$cfrom :: forall o x. Request o -> Rep (Request o) x
Generic, a -> Request b -> Request a
(a -> b) -> Request a -> Request b
(forall a b. (a -> b) -> Request a -> Request b)
-> (forall a b. a -> Request b -> Request a) -> Functor Request
forall a b. a -> Request b -> Request a
forall a b. (a -> b) -> Request a -> Request b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Request b -> Request a
$c<$ :: forall a b. a -> Request b -> Request a
fmap :: (a -> b) -> Request a -> Request b
$cfmap :: forall a b. (a -> b) -> Request a -> Request b
Functor, Request a -> Bool
(a -> m) -> Request a -> m
(a -> b -> b) -> b -> Request a -> b
(forall m. Monoid m => Request m -> m)
-> (forall m a. Monoid m => (a -> m) -> Request a -> m)
-> (forall m a. Monoid m => (a -> m) -> Request a -> m)
-> (forall a b. (a -> b -> b) -> b -> Request a -> b)
-> (forall a b. (a -> b -> b) -> b -> Request a -> b)
-> (forall b a. (b -> a -> b) -> b -> Request a -> b)
-> (forall b a. (b -> a -> b) -> b -> Request a -> b)
-> (forall a. (a -> a -> a) -> Request a -> a)
-> (forall a. (a -> a -> a) -> Request a -> a)
-> (forall a. Request a -> [a])
-> (forall a. Request a -> Bool)
-> (forall a. Request a -> Int)
-> (forall a. Eq a => a -> Request a -> Bool)
-> (forall a. Ord a => Request a -> a)
-> (forall a. Ord a => Request a -> a)
-> (forall a. Num a => Request a -> a)
-> (forall a. Num a => Request a -> a)
-> Foldable Request
forall a. Eq a => a -> Request a -> Bool
forall a. Num a => Request a -> a
forall a. Ord a => Request a -> a
forall m. Monoid m => Request m -> m
forall a. Request a -> Bool
forall a. Request a -> Int
forall a. Request a -> [a]
forall a. (a -> a -> a) -> Request a -> a
forall m a. Monoid m => (a -> m) -> Request a -> m
forall b a. (b -> a -> b) -> b -> Request a -> b
forall a b. (a -> b -> b) -> b -> Request a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: Request a -> a
$cproduct :: forall a. Num a => Request a -> a
sum :: Request a -> a
$csum :: forall a. Num a => Request a -> a
minimum :: Request a -> a
$cminimum :: forall a. Ord a => Request a -> a
maximum :: Request a -> a
$cmaximum :: forall a. Ord a => Request a -> a
elem :: a -> Request a -> Bool
$celem :: forall a. Eq a => a -> Request a -> Bool
length :: Request a -> Int
$clength :: forall a. Request a -> Int
null :: Request a -> Bool
$cnull :: forall a. Request a -> Bool
toList :: Request a -> [a]
$ctoList :: forall a. Request a -> [a]
foldl1 :: (a -> a -> a) -> Request a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Request a -> a
foldr1 :: (a -> a -> a) -> Request a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> Request a -> a
foldl' :: (b -> a -> b) -> b -> Request a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> Request a -> b
foldl :: (b -> a -> b) -> b -> Request a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> Request a -> b
foldr' :: (a -> b -> b) -> b -> Request a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> Request a -> b
foldr :: (a -> b -> b) -> b -> Request a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> Request a -> b
foldMap' :: (a -> m) -> Request a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> Request a -> m
foldMap :: (a -> m) -> Request a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Request a -> m
fold :: Request m -> m
$cfold :: forall m. Monoid m => Request m -> m
Foldable, Functor Request
Foldable Request
Functor Request
-> Foldable Request
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> Request a -> f (Request b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    Request (f a) -> f (Request a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Request a -> m (Request b))
-> (forall (m :: * -> *) a.
    Monad m =>
    Request (m a) -> m (Request a))
-> Traversable Request
(a -> f b) -> Request a -> f (Request b)
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a. Monad m => Request (m a) -> m (Request a)
forall (f :: * -> *) a.
Applicative f =>
Request (f a) -> f (Request a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Request a -> m (Request b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Request a -> f (Request b)
sequence :: Request (m a) -> m (Request a)
$csequence :: forall (m :: * -> *) a. Monad m => Request (m a) -> m (Request a)
mapM :: (a -> m b) -> Request a -> m (Request b)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Request a -> m (Request b)
sequenceA :: Request (f a) -> f (Request a)
$csequenceA :: forall (f :: * -> *) a.
Applicative f =>
Request (f a) -> f (Request a)
traverse :: (a -> f b) -> Request a -> f (Request b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Request a -> f (Request b)
$cp2Traversable :: Foldable Request
$cp1Traversable :: Functor Request
Traversable)
           deriving anyclass ([Request o] -> Encoding
[Request o] -> Value
Request o -> Encoding
Request o -> Value
(Request o -> Value)
-> (Request o -> Encoding)
-> ([Request o] -> Value)
-> ([Request o] -> Encoding)
-> ToJSON (Request o)
forall o. ToJSON o => [Request o] -> Encoding
forall o. ToJSON o => [Request o] -> Value
forall o. ToJSON o => Request o -> Encoding
forall o. ToJSON o => Request o -> Value
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [Request o] -> Encoding
$ctoEncodingList :: forall o. ToJSON o => [Request o] -> Encoding
toJSONList :: [Request o] -> Value
$ctoJSONList :: forall o. ToJSON o => [Request o] -> Value
toEncoding :: Request o -> Encoding
$ctoEncoding :: forall o. ToJSON o => Request o -> Encoding
toJSON :: Request o -> Value
$ctoJSON :: forall o. ToJSON o => Request o -> Value
ToJSON, Value -> Parser [Request o]
Value -> Parser (Request o)
(Value -> Parser (Request o))
-> (Value -> Parser [Request o]) -> FromJSON (Request o)
forall o. FromJSON o => Value -> Parser [Request o]
forall o. FromJSON o => Value -> Parser (Request o)
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [Request o]
$cparseJSONList :: forall o. FromJSON o => Value -> Parser [Request o]
parseJSON :: Value -> Parser (Request o)
$cparseJSON :: forall o. FromJSON o => Value -> Parser (Request o)
FromJSON)

instance Pretty o => Pretty (Request o) where
    pretty :: Request o -> Doc ann
pretty Request{RequestID
rqID :: RequestID
rqID :: forall o. Request o -> RequestID
rqID, IterationID
itID :: IterationID
itID :: forall o. Request o -> IterationID
itID, o
rqRequest :: o
rqRequest :: forall o. Request o -> o
rqRequest} =
        Int -> Doc ann -> Doc ann
forall ann. Int -> Doc ann -> Doc ann
indent Int
2 (Doc ann -> Doc ann) -> Doc ann -> Doc ann
forall a b. (a -> b) -> a -> b
$ [Doc ann] -> Doc ann
forall ann. [Doc ann] -> Doc ann
vsep [
            Doc ann
"Iteration" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> IterationID -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty IterationID
itID Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ann
"request ID" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> RequestID -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty RequestID
rqID,
            Doc ann
"Request:" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> o -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty o
rqRequest
        ]

data Response i =
    Response
        { Response i -> RequestID
rspRqID     :: RequestID
        , Response i -> IterationID
rspItID     :: IterationID
        , Response i -> i
rspResponse :: i
        }  deriving stock (Response i -> Response i -> Bool
(Response i -> Response i -> Bool)
-> (Response i -> Response i -> Bool) -> Eq (Response i)
forall i. Eq i => Response i -> Response i -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Response i -> Response i -> Bool
$c/= :: forall i. Eq i => Response i -> Response i -> Bool
== :: Response i -> Response i -> Bool
$c== :: forall i. Eq i => Response i -> Response i -> Bool
Eq, Eq (Response i)
Eq (Response i)
-> (Response i -> Response i -> Ordering)
-> (Response i -> Response i -> Bool)
-> (Response i -> Response i -> Bool)
-> (Response i -> Response i -> Bool)
-> (Response i -> Response i -> Bool)
-> (Response i -> Response i -> Response i)
-> (Response i -> Response i -> Response i)
-> Ord (Response i)
Response i -> Response i -> Bool
Response i -> Response i -> Ordering
Response i -> Response i -> Response i
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall i. Ord i => Eq (Response i)
forall i. Ord i => Response i -> Response i -> Bool
forall i. Ord i => Response i -> Response i -> Ordering
forall i. Ord i => Response i -> Response i -> Response i
min :: Response i -> Response i -> Response i
$cmin :: forall i. Ord i => Response i -> Response i -> Response i
max :: Response i -> Response i -> Response i
$cmax :: forall i. Ord i => Response i -> Response i -> Response i
>= :: Response i -> Response i -> Bool
$c>= :: forall i. Ord i => Response i -> Response i -> Bool
> :: Response i -> Response i -> Bool
$c> :: forall i. Ord i => Response i -> Response i -> Bool
<= :: Response i -> Response i -> Bool
$c<= :: forall i. Ord i => Response i -> Response i -> Bool
< :: Response i -> Response i -> Bool
$c< :: forall i. Ord i => Response i -> Response i -> Bool
compare :: Response i -> Response i -> Ordering
$ccompare :: forall i. Ord i => Response i -> Response i -> Ordering
$cp1Ord :: forall i. Ord i => Eq (Response i)
Ord, Int -> Response i -> ShowS
[Response i] -> ShowS
Response i -> String
(Int -> Response i -> ShowS)
-> (Response i -> String)
-> ([Response i] -> ShowS)
-> Show (Response i)
forall i. Show i => Int -> Response i -> ShowS
forall i. Show i => [Response i] -> ShowS
forall i. Show i => Response i -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Response i] -> ShowS
$cshowList :: forall i. Show i => [Response i] -> ShowS
show :: Response i -> String
$cshow :: forall i. Show i => Response i -> String
showsPrec :: Int -> Response i -> ShowS
$cshowsPrec :: forall i. Show i => Int -> Response i -> ShowS
Show, (forall x. Response i -> Rep (Response i) x)
-> (forall x. Rep (Response i) x -> Response i)
-> Generic (Response i)
forall x. Rep (Response i) x -> Response i
forall x. Response i -> Rep (Response i) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall i x. Rep (Response i) x -> Response i
forall i x. Response i -> Rep (Response i) x
$cto :: forall i x. Rep (Response i) x -> Response i
$cfrom :: forall i x. Response i -> Rep (Response i) x
Generic, a -> Response b -> Response a
(a -> b) -> Response a -> Response b
(forall a b. (a -> b) -> Response a -> Response b)
-> (forall a b. a -> Response b -> Response a) -> Functor Response
forall a b. a -> Response b -> Response a
forall a b. (a -> b) -> Response a -> Response b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Response b -> Response a
$c<$ :: forall a b. a -> Response b -> Response a
fmap :: (a -> b) -> Response a -> Response b
$cfmap :: forall a b. (a -> b) -> Response a -> Response b
Functor, Response a -> Bool
(a -> m) -> Response a -> m
(a -> b -> b) -> b -> Response a -> b
(forall m. Monoid m => Response m -> m)
-> (forall m a. Monoid m => (a -> m) -> Response a -> m)
-> (forall m a. Monoid m => (a -> m) -> Response a -> m)
-> (forall a b. (a -> b -> b) -> b -> Response a -> b)
-> (forall a b. (a -> b -> b) -> b -> Response a -> b)
-> (forall b a. (b -> a -> b) -> b -> Response a -> b)
-> (forall b a. (b -> a -> b) -> b -> Response a -> b)
-> (forall a. (a -> a -> a) -> Response a -> a)
-> (forall a. (a -> a -> a) -> Response a -> a)
-> (forall a. Response a -> [a])
-> (forall a. Response a -> Bool)
-> (forall a. Response a -> Int)
-> (forall a. Eq a => a -> Response a -> Bool)
-> (forall a. Ord a => Response a -> a)
-> (forall a. Ord a => Response a -> a)
-> (forall a. Num a => Response a -> a)
-> (forall a. Num a => Response a -> a)
-> Foldable Response
forall a. Eq a => a -> Response a -> Bool
forall a. Num a => Response a -> a
forall a. Ord a => Response a -> a
forall m. Monoid m => Response m -> m
forall a. Response a -> Bool
forall a. Response a -> Int
forall a. Response a -> [a]
forall a. (a -> a -> a) -> Response a -> a
forall m a. Monoid m => (a -> m) -> Response a -> m
forall b a. (b -> a -> b) -> b -> Response a -> b
forall a b. (a -> b -> b) -> b -> Response a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: Response a -> a
$cproduct :: forall a. Num a => Response a -> a
sum :: Response a -> a
$csum :: forall a. Num a => Response a -> a
minimum :: Response a -> a
$cminimum :: forall a. Ord a => Response a -> a
maximum :: Response a -> a
$cmaximum :: forall a. Ord a => Response a -> a
elem :: a -> Response a -> Bool
$celem :: forall a. Eq a => a -> Response a -> Bool
length :: Response a -> Int
$clength :: forall a. Response a -> Int
null :: Response a -> Bool
$cnull :: forall a. Response a -> Bool
toList :: Response a -> [a]
$ctoList :: forall a. Response a -> [a]
foldl1 :: (a -> a -> a) -> Response a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Response a -> a
foldr1 :: (a -> a -> a) -> Response a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> Response a -> a
foldl' :: (b -> a -> b) -> b -> Response a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> Response a -> b
foldl :: (b -> a -> b) -> b -> Response a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> Response a -> b
foldr' :: (a -> b -> b) -> b -> Response a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> Response a -> b
foldr :: (a -> b -> b) -> b -> Response a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> Response a -> b
foldMap' :: (a -> m) -> Response a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> Response a -> m
foldMap :: (a -> m) -> Response a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Response a -> m
fold :: Response m -> m
$cfold :: forall m. Monoid m => Response m -> m
Foldable, Functor Response
Foldable Response
Functor Response
-> Foldable Response
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> Response a -> f (Response b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    Response (f a) -> f (Response a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Response a -> m (Response b))
-> (forall (m :: * -> *) a.
    Monad m =>
    Response (m a) -> m (Response a))
-> Traversable Response
(a -> f b) -> Response a -> f (Response b)
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a. Monad m => Response (m a) -> m (Response a)
forall (f :: * -> *) a.
Applicative f =>
Response (f a) -> f (Response a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Response a -> m (Response b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Response a -> f (Response b)
sequence :: Response (m a) -> m (Response a)
$csequence :: forall (m :: * -> *) a. Monad m => Response (m a) -> m (Response a)
mapM :: (a -> m b) -> Response a -> m (Response b)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Response a -> m (Response b)
sequenceA :: Response (f a) -> f (Response a)
$csequenceA :: forall (f :: * -> *) a.
Applicative f =>
Response (f a) -> f (Response a)
traverse :: (a -> f b) -> Response a -> f (Response b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Response a -> f (Response b)
$cp2Traversable :: Foldable Response
$cp1Traversable :: Functor Response
Traversable)
           deriving anyclass ([Response i] -> Encoding
[Response i] -> Value
Response i -> Encoding
Response i -> Value
(Response i -> Value)
-> (Response i -> Encoding)
-> ([Response i] -> Value)
-> ([Response i] -> Encoding)
-> ToJSON (Response i)
forall i. ToJSON i => [Response i] -> Encoding
forall i. ToJSON i => [Response i] -> Value
forall i. ToJSON i => Response i -> Encoding
forall i. ToJSON i => Response i -> Value
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [Response i] -> Encoding
$ctoEncodingList :: forall i. ToJSON i => [Response i] -> Encoding
toJSONList :: [Response i] -> Value
$ctoJSONList :: forall i. ToJSON i => [Response i] -> Value
toEncoding :: Response i -> Encoding
$ctoEncoding :: forall i. ToJSON i => Response i -> Encoding
toJSON :: Response i -> Value
$ctoJSON :: forall i. ToJSON i => Response i -> Value
ToJSON, Value -> Parser [Response i]
Value -> Parser (Response i)
(Value -> Parser (Response i))
-> (Value -> Parser [Response i]) -> FromJSON (Response i)
forall i. FromJSON i => Value -> Parser [Response i]
forall i. FromJSON i => Value -> Parser (Response i)
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [Response i]
$cparseJSONList :: forall i. FromJSON i => Value -> Parser [Response i]
parseJSON :: Value -> Parser (Response i)
$cparseJSON :: forall i. FromJSON i => Value -> Parser (Response i)
FromJSON)

instance Pretty i => Pretty (Response i) where
    pretty :: Response i -> Doc ann
pretty Response{RequestID
rspRqID :: RequestID
rspRqID :: forall i. Response i -> RequestID
rspRqID, IterationID
rspItID :: IterationID
rspItID :: forall i. Response i -> IterationID
rspItID, i
rspResponse :: i
rspResponse :: forall i. Response i -> i
rspResponse} =
        Int -> Doc ann -> Doc ann
forall ann. Int -> Doc ann -> Doc ann
indent Int
2 (Doc ann -> Doc ann) -> Doc ann -> Doc ann
forall a b. (a -> b) -> a -> b
$ [Doc ann] -> Doc ann
forall ann. [Doc ann] -> Doc ann
vsep [
            Doc ann
"Iteration" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> IterationID -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty IterationID
rspItID Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ann
"request ID" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> RequestID -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty RequestID
rspRqID,
            Doc ann
"Response:" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> i -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty i
rspResponse
        ]

newtype Requests o = Requests { Requests o -> [Request o]
unRequests :: [Request o] }
    deriving newtype (Requests o -> Requests o -> Bool
(Requests o -> Requests o -> Bool)
-> (Requests o -> Requests o -> Bool) -> Eq (Requests o)
forall o. Eq o => Requests o -> Requests o -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Requests o -> Requests o -> Bool
$c/= :: forall o. Eq o => Requests o -> Requests o -> Bool
== :: Requests o -> Requests o -> Bool
$c== :: forall o. Eq o => Requests o -> Requests o -> Bool
Eq, Eq (Requests o)
Eq (Requests o)
-> (Requests o -> Requests o -> Ordering)
-> (Requests o -> Requests o -> Bool)
-> (Requests o -> Requests o -> Bool)
-> (Requests o -> Requests o -> Bool)
-> (Requests o -> Requests o -> Bool)
-> (Requests o -> Requests o -> Requests o)
-> (Requests o -> Requests o -> Requests o)
-> Ord (Requests o)
Requests o -> Requests o -> Bool
Requests o -> Requests o -> Ordering
Requests o -> Requests o -> Requests o
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall o. Ord o => Eq (Requests o)
forall o. Ord o => Requests o -> Requests o -> Bool
forall o. Ord o => Requests o -> Requests o -> Ordering
forall o. Ord o => Requests o -> Requests o -> Requests o
min :: Requests o -> Requests o -> Requests o
$cmin :: forall o. Ord o => Requests o -> Requests o -> Requests o
max :: Requests o -> Requests o -> Requests o
$cmax :: forall o. Ord o => Requests o -> Requests o -> Requests o
>= :: Requests o -> Requests o -> Bool
$c>= :: forall o. Ord o => Requests o -> Requests o -> Bool
> :: Requests o -> Requests o -> Bool
$c> :: forall o. Ord o => Requests o -> Requests o -> Bool
<= :: Requests o -> Requests o -> Bool
$c<= :: forall o. Ord o => Requests o -> Requests o -> Bool
< :: Requests o -> Requests o -> Bool
$c< :: forall o. Ord o => Requests o -> Requests o -> Bool
compare :: Requests o -> Requests o -> Ordering
$ccompare :: forall o. Ord o => Requests o -> Requests o -> Ordering
$cp1Ord :: forall o. Ord o => Eq (Requests o)
Ord, Int -> Requests o -> ShowS
[Requests o] -> ShowS
Requests o -> String
(Int -> Requests o -> ShowS)
-> (Requests o -> String)
-> ([Requests o] -> ShowS)
-> Show (Requests o)
forall o. Show o => Int -> Requests o -> ShowS
forall o. Show o => [Requests o] -> ShowS
forall o. Show o => Requests o -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Requests o] -> ShowS
$cshowList :: forall o. Show o => [Requests o] -> ShowS
show :: Requests o -> String
$cshow :: forall o. Show o => Requests o -> String
showsPrec :: Int -> Requests o -> ShowS
$cshowsPrec :: forall o. Show o => Int -> Requests o -> ShowS
Show, b -> Requests o -> Requests o
NonEmpty (Requests o) -> Requests o
Requests o -> Requests o -> Requests o
(Requests o -> Requests o -> Requests o)
-> (NonEmpty (Requests o) -> Requests o)
-> (forall b. Integral b => b -> Requests o -> Requests o)
-> Semigroup (Requests o)
forall b. Integral b => b -> Requests o -> Requests o
forall o. NonEmpty (Requests o) -> Requests o
forall o. Requests o -> Requests o -> Requests o
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
forall o b. Integral b => b -> Requests o -> Requests o
stimes :: b -> Requests o -> Requests o
$cstimes :: forall o b. Integral b => b -> Requests o -> Requests o
sconcat :: NonEmpty (Requests o) -> Requests o
$csconcat :: forall o. NonEmpty (Requests o) -> Requests o
<> :: Requests o -> Requests o -> Requests o
$c<> :: forall o. Requests o -> Requests o -> Requests o
Semigroup, Semigroup (Requests o)
Requests o
Semigroup (Requests o)
-> Requests o
-> (Requests o -> Requests o -> Requests o)
-> ([Requests o] -> Requests o)
-> Monoid (Requests o)
[Requests o] -> Requests o
Requests o -> Requests o -> Requests o
forall o. Semigroup (Requests o)
forall o. Requests o
forall a.
Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
forall o. [Requests o] -> Requests o
forall o. Requests o -> Requests o -> Requests o
mconcat :: [Requests o] -> Requests o
$cmconcat :: forall o. [Requests o] -> Requests o
mappend :: Requests o -> Requests o -> Requests o
$cmappend :: forall o. Requests o -> Requests o -> Requests o
mempty :: Requests o
$cmempty :: forall o. Requests o
$cp1Monoid :: forall o. Semigroup (Requests o)
Monoid)
    deriving anyclass ([Requests o] -> Encoding
[Requests o] -> Value
Requests o -> Encoding
Requests o -> Value
(Requests o -> Value)
-> (Requests o -> Encoding)
-> ([Requests o] -> Value)
-> ([Requests o] -> Encoding)
-> ToJSON (Requests o)
forall o. ToJSON o => [Requests o] -> Encoding
forall o. ToJSON o => [Requests o] -> Value
forall o. ToJSON o => Requests o -> Encoding
forall o. ToJSON o => Requests o -> Value
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [Requests o] -> Encoding
$ctoEncodingList :: forall o. ToJSON o => [Requests o] -> Encoding
toJSONList :: [Requests o] -> Value
$ctoJSONList :: forall o. ToJSON o => [Requests o] -> Value
toEncoding :: Requests o -> Encoding
$ctoEncoding :: forall o. ToJSON o => Requests o -> Encoding
toJSON :: Requests o -> Value
$ctoJSON :: forall o. ToJSON o => Requests o -> Value
ToJSON, Value -> Parser [Requests o]
Value -> Parser (Requests o)
(Value -> Parser (Requests o))
-> (Value -> Parser [Requests o]) -> FromJSON (Requests o)
forall o. FromJSON o => Value -> Parser [Requests o]
forall o. FromJSON o => Value -> Parser (Requests o)
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [Requests o]
$cparseJSONList :: forall o. FromJSON o => Value -> Parser [Requests o]
parseJSON :: Value -> Parser (Requests o)
$cparseJSON :: forall o. FromJSON o => Value -> Parser (Requests o)
FromJSON)
    deriving stock ((forall x. Requests o -> Rep (Requests o) x)
-> (forall x. Rep (Requests o) x -> Requests o)
-> Generic (Requests o)
forall x. Rep (Requests o) x -> Requests o
forall x. Requests o -> Rep (Requests o) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall o x. Rep (Requests o) x -> Requests o
forall o x. Requests o -> Rep (Requests o) x
$cto :: forall o x. Rep (Requests o) x -> Requests o
$cfrom :: forall o x. Requests o -> Rep (Requests o) x
Generic, a -> Requests b -> Requests a
(a -> b) -> Requests a -> Requests b
(forall a b. (a -> b) -> Requests a -> Requests b)
-> (forall a b. a -> Requests b -> Requests a) -> Functor Requests
forall a b. a -> Requests b -> Requests a
forall a b. (a -> b) -> Requests a -> Requests b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Requests b -> Requests a
$c<$ :: forall a b. a -> Requests b -> Requests a
fmap :: (a -> b) -> Requests a -> Requests b
$cfmap :: forall a b. (a -> b) -> Requests a -> Requests b
Functor, Requests a -> Bool
(a -> m) -> Requests a -> m
(a -> b -> b) -> b -> Requests a -> b
(forall m. Monoid m => Requests m -> m)
-> (forall m a. Monoid m => (a -> m) -> Requests a -> m)
-> (forall m a. Monoid m => (a -> m) -> Requests a -> m)
-> (forall a b. (a -> b -> b) -> b -> Requests a -> b)
-> (forall a b. (a -> b -> b) -> b -> Requests a -> b)
-> (forall b a. (b -> a -> b) -> b -> Requests a -> b)
-> (forall b a. (b -> a -> b) -> b -> Requests a -> b)
-> (forall a. (a -> a -> a) -> Requests a -> a)
-> (forall a. (a -> a -> a) -> Requests a -> a)
-> (forall a. Requests a -> [a])
-> (forall a. Requests a -> Bool)
-> (forall a. Requests a -> Int)
-> (forall a. Eq a => a -> Requests a -> Bool)
-> (forall a. Ord a => Requests a -> a)
-> (forall a. Ord a => Requests a -> a)
-> (forall a. Num a => Requests a -> a)
-> (forall a. Num a => Requests a -> a)
-> Foldable Requests
forall a. Eq a => a -> Requests a -> Bool
forall a. Num a => Requests a -> a
forall a. Ord a => Requests a -> a
forall m. Monoid m => Requests m -> m
forall a. Requests a -> Bool
forall a. Requests a -> Int
forall a. Requests a -> [a]
forall a. (a -> a -> a) -> Requests a -> a
forall m a. Monoid m => (a -> m) -> Requests a -> m
forall b a. (b -> a -> b) -> b -> Requests a -> b
forall a b. (a -> b -> b) -> b -> Requests a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: Requests a -> a
$cproduct :: forall a. Num a => Requests a -> a
sum :: Requests a -> a
$csum :: forall a. Num a => Requests a -> a
minimum :: Requests a -> a
$cminimum :: forall a. Ord a => Requests a -> a
maximum :: Requests a -> a
$cmaximum :: forall a. Ord a => Requests a -> a
elem :: a -> Requests a -> Bool
$celem :: forall a. Eq a => a -> Requests a -> Bool
length :: Requests a -> Int
$clength :: forall a. Requests a -> Int
null :: Requests a -> Bool
$cnull :: forall a. Requests a -> Bool
toList :: Requests a -> [a]
$ctoList :: forall a. Requests a -> [a]
foldl1 :: (a -> a -> a) -> Requests a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Requests a -> a
foldr1 :: (a -> a -> a) -> Requests a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> Requests a -> a
foldl' :: (b -> a -> b) -> b -> Requests a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> Requests a -> b
foldl :: (b -> a -> b) -> b -> Requests a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> Requests a -> b
foldr' :: (a -> b -> b) -> b -> Requests a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> Requests a -> b
foldr :: (a -> b -> b) -> b -> Requests a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> Requests a -> b
foldMap' :: (a -> m) -> Requests a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> Requests a -> m
foldMap :: (a -> m) -> Requests a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Requests a -> m
fold :: Requests m -> m
$cfold :: forall m. Monoid m => Requests m -> m
Foldable, Functor Requests
Foldable Requests
Functor Requests
-> Foldable Requests
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> Requests a -> f (Requests b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    Requests (f a) -> f (Requests a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Requests a -> m (Requests b))
-> (forall (m :: * -> *) a.
    Monad m =>
    Requests (m a) -> m (Requests a))
-> Traversable Requests
(a -> f b) -> Requests a -> f (Requests b)
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a. Monad m => Requests (m a) -> m (Requests a)
forall (f :: * -> *) a.
Applicative f =>
Requests (f a) -> f (Requests a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Requests a -> m (Requests b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Requests a -> f (Requests b)
sequence :: Requests (m a) -> m (Requests a)
$csequence :: forall (m :: * -> *) a. Monad m => Requests (m a) -> m (Requests a)
mapM :: (a -> m b) -> Requests a -> m (Requests b)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Requests a -> m (Requests b)
sequenceA :: Requests (f a) -> f (Requests a)
$csequenceA :: forall (f :: * -> *) a.
Applicative f =>
Requests (f a) -> f (Requests a)
traverse :: (a -> f b) -> Requests a -> f (Requests b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Requests a -> f (Requests b)
$cp2Traversable :: Foldable Requests
$cp1Traversable :: Functor Requests
Traversable)

instance Pretty o => Pretty (Requests o) where
    pretty :: Requests o -> Doc ann
pretty Requests{[Request o]
unRequests :: [Request o]
unRequests :: forall o. Requests o -> [Request o]
unRequests} =
        Int -> Doc ann -> Doc ann
forall ann. Int -> Doc ann -> Doc ann
indent Int
2 (Doc ann -> Doc ann) -> Doc ann -> Doc ann
forall a b. (a -> b) -> a -> b
$ [Doc ann] -> Doc ann
forall ann. [Doc ann] -> Doc ann
vsep (Doc ann
"Requests:" Doc ann -> [Doc ann] -> [Doc ann]
forall a. a -> [a] -> [a]
: (Request o -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty (Request o -> Doc ann) -> [Request o] -> [Doc ann]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Request o]
unRequests))

newtype Responses i = Responses { Responses i -> Map (IterationID, RequestID) i
unResponses :: Map (IterationID, RequestID) i }
    deriving newtype (Responses i -> Responses i -> Bool
(Responses i -> Responses i -> Bool)
-> (Responses i -> Responses i -> Bool) -> Eq (Responses i)
forall i. Eq i => Responses i -> Responses i -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Responses i -> Responses i -> Bool
$c/= :: forall i. Eq i => Responses i -> Responses i -> Bool
== :: Responses i -> Responses i -> Bool
$c== :: forall i. Eq i => Responses i -> Responses i -> Bool
Eq, Eq (Responses i)
Eq (Responses i)
-> (Responses i -> Responses i -> Ordering)
-> (Responses i -> Responses i -> Bool)
-> (Responses i -> Responses i -> Bool)
-> (Responses i -> Responses i -> Bool)
-> (Responses i -> Responses i -> Bool)
-> (Responses i -> Responses i -> Responses i)
-> (Responses i -> Responses i -> Responses i)
-> Ord (Responses i)
Responses i -> Responses i -> Bool
Responses i -> Responses i -> Ordering
Responses i -> Responses i -> Responses i
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall i. Ord i => Eq (Responses i)
forall i. Ord i => Responses i -> Responses i -> Bool
forall i. Ord i => Responses i -> Responses i -> Ordering
forall i. Ord i => Responses i -> Responses i -> Responses i
min :: Responses i -> Responses i -> Responses i
$cmin :: forall i. Ord i => Responses i -> Responses i -> Responses i
max :: Responses i -> Responses i -> Responses i
$cmax :: forall i. Ord i => Responses i -> Responses i -> Responses i
>= :: Responses i -> Responses i -> Bool
$c>= :: forall i. Ord i => Responses i -> Responses i -> Bool
> :: Responses i -> Responses i -> Bool
$c> :: forall i. Ord i => Responses i -> Responses i -> Bool
<= :: Responses i -> Responses i -> Bool
$c<= :: forall i. Ord i => Responses i -> Responses i -> Bool
< :: Responses i -> Responses i -> Bool
$c< :: forall i. Ord i => Responses i -> Responses i -> Bool
compare :: Responses i -> Responses i -> Ordering
$ccompare :: forall i. Ord i => Responses i -> Responses i -> Ordering
$cp1Ord :: forall i. Ord i => Eq (Responses i)
Ord, Int -> Responses i -> ShowS
[Responses i] -> ShowS
Responses i -> String
(Int -> Responses i -> ShowS)
-> (Responses i -> String)
-> ([Responses i] -> ShowS)
-> Show (Responses i)
forall i. Show i => Int -> Responses i -> ShowS
forall i. Show i => [Responses i] -> ShowS
forall i. Show i => Responses i -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Responses i] -> ShowS
$cshowList :: forall i. Show i => [Responses i] -> ShowS
show :: Responses i -> String
$cshow :: forall i. Show i => Responses i -> String
showsPrec :: Int -> Responses i -> ShowS
$cshowsPrec :: forall i. Show i => Int -> Responses i -> ShowS
Show, b -> Responses i -> Responses i
NonEmpty (Responses i) -> Responses i
Responses i -> Responses i -> Responses i
(Responses i -> Responses i -> Responses i)
-> (NonEmpty (Responses i) -> Responses i)
-> (forall b. Integral b => b -> Responses i -> Responses i)
-> Semigroup (Responses i)
forall b. Integral b => b -> Responses i -> Responses i
forall i. NonEmpty (Responses i) -> Responses i
forall i. Responses i -> Responses i -> Responses i
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
forall i b. Integral b => b -> Responses i -> Responses i
stimes :: b -> Responses i -> Responses i
$cstimes :: forall i b. Integral b => b -> Responses i -> Responses i
sconcat :: NonEmpty (Responses i) -> Responses i
$csconcat :: forall i. NonEmpty (Responses i) -> Responses i
<> :: Responses i -> Responses i -> Responses i
$c<> :: forall i. Responses i -> Responses i -> Responses i
Semigroup, Semigroup (Responses i)
Responses i
Semigroup (Responses i)
-> Responses i
-> (Responses i -> Responses i -> Responses i)
-> ([Responses i] -> Responses i)
-> Monoid (Responses i)
[Responses i] -> Responses i
Responses i -> Responses i -> Responses i
forall i. Semigroup (Responses i)
forall i. Responses i
forall a.
Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
forall i. [Responses i] -> Responses i
forall i. Responses i -> Responses i -> Responses i
mconcat :: [Responses i] -> Responses i
$cmconcat :: forall i. [Responses i] -> Responses i
mappend :: Responses i -> Responses i -> Responses i
$cmappend :: forall i. Responses i -> Responses i -> Responses i
mempty :: Responses i
$cmempty :: forall i. Responses i
$cp1Monoid :: forall i. Semigroup (Responses i)
Monoid)
    deriving anyclass ([Responses i] -> Encoding
[Responses i] -> Value
Responses i -> Encoding
Responses i -> Value
(Responses i -> Value)
-> (Responses i -> Encoding)
-> ([Responses i] -> Value)
-> ([Responses i] -> Encoding)
-> ToJSON (Responses i)
forall i. ToJSON i => [Responses i] -> Encoding
forall i. ToJSON i => [Responses i] -> Value
forall i. ToJSON i => Responses i -> Encoding
forall i. ToJSON i => Responses i -> Value
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [Responses i] -> Encoding
$ctoEncodingList :: forall i. ToJSON i => [Responses i] -> Encoding
toJSONList :: [Responses i] -> Value
$ctoJSONList :: forall i. ToJSON i => [Responses i] -> Value
toEncoding :: Responses i -> Encoding
$ctoEncoding :: forall i. ToJSON i => Responses i -> Encoding
toJSON :: Responses i -> Value
$ctoJSON :: forall i. ToJSON i => Responses i -> Value
ToJSON, Value -> Parser [Responses i]
Value -> Parser (Responses i)
(Value -> Parser (Responses i))
-> (Value -> Parser [Responses i]) -> FromJSON (Responses i)
forall i. FromJSON i => Value -> Parser [Responses i]
forall i. FromJSON i => Value -> Parser (Responses i)
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [Responses i]
$cparseJSONList :: forall i. FromJSON i => Value -> Parser [Responses i]
parseJSON :: Value -> Parser (Responses i)
$cparseJSON :: forall i. FromJSON i => Value -> Parser (Responses i)
FromJSON)
    deriving stock ((forall x. Responses i -> Rep (Responses i) x)
-> (forall x. Rep (Responses i) x -> Responses i)
-> Generic (Responses i)
forall x. Rep (Responses i) x -> Responses i
forall x. Responses i -> Rep (Responses i) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall i x. Rep (Responses i) x -> Responses i
forall i x. Responses i -> Rep (Responses i) x
$cto :: forall i x. Rep (Responses i) x -> Responses i
$cfrom :: forall i x. Responses i -> Rep (Responses i) x
Generic, a -> Responses b -> Responses a
(a -> b) -> Responses a -> Responses b
(forall a b. (a -> b) -> Responses a -> Responses b)
-> (forall a b. a -> Responses b -> Responses a)
-> Functor Responses
forall a b. a -> Responses b -> Responses a
forall a b. (a -> b) -> Responses a -> Responses b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Responses b -> Responses a
$c<$ :: forall a b. a -> Responses b -> Responses a
fmap :: (a -> b) -> Responses a -> Responses b
$cfmap :: forall a b. (a -> b) -> Responses a -> Responses b
Functor, Responses a -> Bool
(a -> m) -> Responses a -> m
(a -> b -> b) -> b -> Responses a -> b
(forall m. Monoid m => Responses m -> m)
-> (forall m a. Monoid m => (a -> m) -> Responses a -> m)
-> (forall m a. Monoid m => (a -> m) -> Responses a -> m)
-> (forall a b. (a -> b -> b) -> b -> Responses a -> b)
-> (forall a b. (a -> b -> b) -> b -> Responses a -> b)
-> (forall b a. (b -> a -> b) -> b -> Responses a -> b)
-> (forall b a. (b -> a -> b) -> b -> Responses a -> b)
-> (forall a. (a -> a -> a) -> Responses a -> a)
-> (forall a. (a -> a -> a) -> Responses a -> a)
-> (forall a. Responses a -> [a])
-> (forall a. Responses a -> Bool)
-> (forall a. Responses a -> Int)
-> (forall a. Eq a => a -> Responses a -> Bool)
-> (forall a. Ord a => Responses a -> a)
-> (forall a. Ord a => Responses a -> a)
-> (forall a. Num a => Responses a -> a)
-> (forall a. Num a => Responses a -> a)
-> Foldable Responses
forall a. Eq a => a -> Responses a -> Bool
forall a. Num a => Responses a -> a
forall a. Ord a => Responses a -> a
forall m. Monoid m => Responses m -> m
forall a. Responses a -> Bool
forall a. Responses a -> Int
forall a. Responses a -> [a]
forall a. (a -> a -> a) -> Responses a -> a
forall m a. Monoid m => (a -> m) -> Responses a -> m
forall b a. (b -> a -> b) -> b -> Responses a -> b
forall a b. (a -> b -> b) -> b -> Responses a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: Responses a -> a
$cproduct :: forall a. Num a => Responses a -> a
sum :: Responses a -> a
$csum :: forall a. Num a => Responses a -> a
minimum :: Responses a -> a
$cminimum :: forall a. Ord a => Responses a -> a
maximum :: Responses a -> a
$cmaximum :: forall a. Ord a => Responses a -> a
elem :: a -> Responses a -> Bool
$celem :: forall a. Eq a => a -> Responses a -> Bool
length :: Responses a -> Int
$clength :: forall a. Responses a -> Int
null :: Responses a -> Bool
$cnull :: forall a. Responses a -> Bool
toList :: Responses a -> [a]
$ctoList :: forall a. Responses a -> [a]
foldl1 :: (a -> a -> a) -> Responses a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Responses a -> a
foldr1 :: (a -> a -> a) -> Responses a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> Responses a -> a
foldl' :: (b -> a -> b) -> b -> Responses a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> Responses a -> b
foldl :: (b -> a -> b) -> b -> Responses a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> Responses a -> b
foldr' :: (a -> b -> b) -> b -> Responses a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> Responses a -> b
foldr :: (a -> b -> b) -> b -> Responses a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> Responses a -> b
foldMap' :: (a -> m) -> Responses a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> Responses a -> m
foldMap :: (a -> m) -> Responses a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Responses a -> m
fold :: Responses m -> m
$cfold :: forall m. Monoid m => Responses m -> m
Foldable, Functor Responses
Foldable Responses
Functor Responses
-> Foldable Responses
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> Responses a -> f (Responses b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    Responses (f a) -> f (Responses a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Responses a -> m (Responses b))
-> (forall (m :: * -> *) a.
    Monad m =>
    Responses (m a) -> m (Responses a))
-> Traversable Responses
(a -> f b) -> Responses a -> f (Responses b)
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a.
Monad m =>
Responses (m a) -> m (Responses a)
forall (f :: * -> *) a.
Applicative f =>
Responses (f a) -> f (Responses a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Responses a -> m (Responses b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Responses a -> f (Responses b)
sequence :: Responses (m a) -> m (Responses a)
$csequence :: forall (m :: * -> *) a.
Monad m =>
Responses (m a) -> m (Responses a)
mapM :: (a -> m b) -> Responses a -> m (Responses b)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Responses a -> m (Responses b)
sequenceA :: Responses (f a) -> f (Responses a)
$csequenceA :: forall (f :: * -> *) a.
Applicative f =>
Responses (f a) -> f (Responses a)
traverse :: (a -> f b) -> Responses a -> f (Responses b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Responses a -> f (Responses b)
$cp2Traversable :: Foldable Responses
$cp1Traversable :: Functor Responses
Traversable)

_Responses :: forall i. Iso' (Responses i) (Map (IterationID, RequestID) i)
_Responses :: p (Map (IterationID, RequestID) i)
  (f (Map (IterationID, RequestID) i))
-> p (Responses i) (f (Responses i))
_Responses = (Responses i -> Map (IterationID, RequestID) i)
-> (Map (IterationID, RequestID) i -> Responses i)
-> Iso
     (Responses i)
     (Responses i)
     (Map (IterationID, RequestID) i)
     (Map (IterationID, RequestID) i)
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso Responses i -> Map (IterationID, RequestID) i
forall i. Responses i -> Map (IterationID, RequestID) i
unResponses Map (IterationID, RequestID) i -> Responses i
forall i. Map (IterationID, RequestID) i -> Responses i
Responses

-- | A list of all responses ordered by iteration and request ID
responses :: Responses i -> [Response i]
responses :: Responses i -> [Response i]
responses =
    let mkResp :: (IterationID, RequestID) -> i -> Response i
mkResp (IterationID
itId, RequestID
rqId) i
evt = Response :: forall i. RequestID -> IterationID -> i -> Response i
Response{rspRqID :: RequestID
rspRqID = RequestID
rqId, rspItID :: IterationID
rspItID = IterationID
itId, rspResponse :: i
rspResponse=i
evt}
    in (((IterationID, RequestID), i) -> Response i)
-> [((IterationID, RequestID), i)] -> [Response i]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((IterationID, RequestID) -> i -> Response i)
-> ((IterationID, RequestID), i) -> Response i
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (IterationID, RequestID) -> i -> Response i
forall i. (IterationID, RequestID) -> i -> Response i
mkResp) ([((IterationID, RequestID), i)] -> [Response i])
-> (Responses i -> [((IterationID, RequestID), i)])
-> Responses i
-> [Response i]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map (IterationID, RequestID) i -> [((IterationID, RequestID), i)]
forall k a. Map k a -> [(k, a)]
Map.toAscList (Map (IterationID, RequestID) i -> [((IterationID, RequestID), i)])
-> (Responses i -> Map (IterationID, RequestID) i)
-> Responses i
-> [((IterationID, RequestID), i)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Responses i -> Map (IterationID, RequestID) i
forall i. Responses i -> Map (IterationID, RequestID) i
unResponses

instance Pretty i => Pretty (Responses i) where
    pretty :: Responses i -> Doc ann
pretty (Responses Map (IterationID, RequestID) i
mp) =
        let entries :: [((IterationID, RequestID), i)]
entries = Map (IterationID, RequestID) i -> [((IterationID, RequestID), i)]
forall k a. Map k a -> [(k, a)]
Map.toList Map (IterationID, RequestID) i
mp
            prettyEntry :: ((a, a), a) -> Doc ann
prettyEntry ((a
itID, a
reqID), a
i) =
                Int -> Doc ann -> Doc ann
forall ann. Int -> Doc ann -> Doc ann
hang Int
2 (Doc ann -> Doc ann) -> Doc ann -> Doc ann
forall a b. (a -> b) -> a -> b
$ [Doc ann] -> Doc ann
forall ann. [Doc ann] -> Doc ann
vsep [Doc ann
"IterationID:" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> a -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty a
itID, Doc ann
"RequestID:" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> a -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty a
reqID, Doc ann
"Event:" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> a -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty a
i]
        in [Doc ann] -> Doc ann
forall ann. [Doc ann] -> Doc ann
vsep (((IterationID, RequestID), i) -> Doc ann
forall a a a ann.
(Pretty a, Pretty a, Pretty a) =>
((a, a), a) -> Doc ann
prettyEntry (((IterationID, RequestID), i) -> Doc ann)
-> [((IterationID, RequestID), i)] -> [Doc ann]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [((IterationID, RequestID), i)]
entries)

{- Note [Running resumable programs]

Running 'Resumable' programs involves two stages. First we transform the programs
into ones that use the 'NonDet' and 'Yield' effects that come with
'freer-simple'. Then we interpret the resulting program with 'Reader' and
'State' effects to capture the state of open requests.

#### Stage 1

Stage 1 is implemented in 'handleResumable'. The result is a program that uses
'NonDet' and 'Yield' in a very specific way to implement the resumable
functionality. The reason why we don't say something like @type Resumable effs
= Members '[NonDet, Yield] effs@ instead of the 'Resumable' data type is that
'NonDet' allows for backtracking, which we do not want to expose to the users.

The programs produced by 'handleResumable' have at most one level of
backtracking (to the next call to 'prompt'). There is no 'empty'
constructor (and no 'Alternative' instance for contracts) because the only
thing that can cause backtracking to happen is the provisioning of an answer
to a 'prompt' call from the environment.

#### Stage 2

Stage 2 is implemented in 'suspendNonDet'. Here we handle the 'Yield' and
'NonDet' effects that were introduced in the previous stage. In this stage we
assign two numbers to each request issued by the contract, a 'RequestID' and an
'IterationID'. The request ID is simply a consecutive numbering of every
request that is made during the lifetime of the contract. The iteration ID is
unique for each group of open requests that the contract produces.

Of particular importance is the 'runStep' function, which deals with the
'Status' values that we get from 'runC'. It uses the 'ResumableEffs' effects:

>>> type ResumableEffs i o effs = State IterationID ': NonDet ': State RequestID ': effs

Note that the 'IterationID' state comes before 'NonDet', and the 'RequestID'
state comes after 'NonDet'. This is done so that we increase the 'RequestID'
whenever a request is made, and the 'IterationID' only when a request is
answered.

-}

-- Effects that are used to interpret the Yield/NonDet combination
-- produced by 'handleResumable'.
type ResumableEffs i o effs a =
    -- anything that comes before 'NonDet' can be backtracked.
     NonDet
     ': State IterationID
     ': State RequestID
     ': State (ReqMap i o effs a)
     ': State (Requests o)
     ': effs

-- | Interpret the 'Resumable' effect in terms of the 'Yield' and 'NonDet'
--   effects.
handleResumable ::
    forall i o effs.
    ( Member (Yield o i) effs
    , Member NonDet effs
    )
    => Eff (Resumable i o ': effs)
    ~> Eff effs
handleResumable :: Eff (Resumable i o : effs) ~> Eff effs
handleResumable = (Resumable i o ~> Eff effs)
-> Eff (Resumable i o : effs) ~> Eff effs
forall (eff :: * -> *) (effs :: [* -> *]).
(eff ~> Eff effs) -> Eff (eff : effs) ~> Eff effs
interpret ((Resumable i o ~> Eff effs)
 -> Eff (Resumable i o : effs) ~> Eff effs)
-> (Resumable i o ~> Eff effs)
-> Eff (Resumable i o : effs) ~> Eff effs
forall a b. (a -> b) -> a -> b
$ \case
    RRequest o -> o -> (x -> x) -> Eff effs x
forall a b (effs :: [* -> *]) c.
Member (Yield a b) effs =>
a -> (b -> c) -> Eff effs c
yield o
o x -> x
forall a. a -> a
id
    Resumable i o x
RSelect    -> NonDet Bool -> Eff effs Bool
forall (eff :: * -> *) (effs :: [* -> *]) a.
Member eff effs =>
eff a -> Eff effs a
send NonDet Bool
MPlus
    Resumable i o x
RZero      -> NonDet x -> Eff effs x
forall (eff :: * -> *) (effs :: [* -> *]) a.
Member eff effs =>
eff a -> Eff effs a
send NonDet x
forall a. NonDet a
MZero

-- | Status of a suspended 'MultiRequestContinuation'.
data MultiRequestContStatus i o effs a =
    -- | Done
    AResult a
     -- | Waiting for inputs
    | AContinuation (MultiRequestContinuation i o effs a)

-- | A continuation that accepts a response to one of several requests.
data MultiRequestContinuation i o effs a =
    MultiRequestContinuation
        { MultiRequestContinuation i o effs a
-> Response i
-> Eff effs (Maybe (MultiRequestContStatus i o effs a))
ndcCont     :: Response i -> Eff effs (Maybe (MultiRequestContStatus i o effs a)) -- ^ Continuation for the response
        , MultiRequestContinuation i o effs a -> Requests o
ndcRequests :: Requests o -- ^ The list of all open requests.
        }

-- | A map of requests to continuations. For each request, identified by
--   a pair of 'RequestID' and 'IterationID', 'ReqMap' contains the
--   continuation that takes the response to the request.
newtype ReqMap i o effs a = ReqMap { ReqMap i o effs a
-> Map
     (RequestID, IterationID) (i -> Eff (ResumableEffs i o effs a) a)
unReqMap :: Map (RequestID, IterationID) (i -> Eff (ResumableEffs i o effs a) a) }

insertRequest :: (RequestID, IterationID) -> (i -> Eff (ResumableEffs i o effs a) a) -> ReqMap i o effs a -> ReqMap i o effs a
insertRequest :: (RequestID, IterationID)
-> (i -> Eff (ResumableEffs i o effs a) a)
-> ReqMap i o effs a
-> ReqMap i o effs a
insertRequest (RequestID, IterationID)
k i -> Eff (ResumableEffs i o effs a) a
v = Map
  (RequestID, IterationID) (i -> Eff (ResumableEffs i o effs a) a)
-> ReqMap i o effs a
forall i o (effs :: [* -> *]) a.
Map
  (RequestID, IterationID) (i -> Eff (ResumableEffs i o effs a) a)
-> ReqMap i o effs a
ReqMap (Map
   (RequestID, IterationID) (i -> Eff (ResumableEffs i o effs a) a)
 -> ReqMap i o effs a)
-> (ReqMap i o effs a
    -> Map
         (RequestID, IterationID) (i -> Eff (ResumableEffs i o effs a) a))
-> ReqMap i o effs a
-> ReqMap i o effs a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (RequestID, IterationID)
-> (i -> Eff (ResumableEffs i o effs a) a)
-> Map
     (RequestID, IterationID) (i -> Eff (ResumableEffs i o effs a) a)
-> Map
     (RequestID, IterationID) (i -> Eff (ResumableEffs i o effs a) a)
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert (RequestID, IterationID)
k i -> Eff (ResumableEffs i o effs a) a
v (Map
   (RequestID, IterationID) (i -> Eff (ResumableEffs i o effs a) a)
 -> Map
      (RequestID, IterationID) (i -> Eff (ResumableEffs i o effs a) a))
-> (ReqMap i o effs a
    -> Map
         (RequestID, IterationID) (i -> Eff (ResumableEffs i o effs a) a))
-> ReqMap i o effs a
-> Map
     (RequestID, IterationID) (i -> Eff (ResumableEffs i o effs a) a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReqMap i o effs a
-> Map
     (RequestID, IterationID) (i -> Eff (ResumableEffs i o effs a) a)
forall i o (effs :: [* -> *]) a.
ReqMap i o effs a
-> Map
     (RequestID, IterationID) (i -> Eff (ResumableEffs i o effs a) a)
unReqMap

-- | Handle the 'ResumableEffs' effects, returning a new suspended
--   computation.
runSuspInt ::
    forall i o a effs.
    Eff (ResumableEffs i o effs a) a
    -> Eff effs (Maybe (MultiRequestContStatus i o effs a))
runSuspInt :: Eff (ResumableEffs i o effs a) a
-> Eff effs (Maybe (MultiRequestContStatus i o effs a))
runSuspInt = IterationID
-> Eff (ResumableEffs i o effs a) a
-> Eff effs (Maybe (MultiRequestContStatus i o effs a))
go IterationID
1 where
    go :: IterationID
-> Eff (ResumableEffs i o effs a) a
-> Eff effs (Maybe (MultiRequestContStatus i o effs a))
go IterationID
currentIteration Eff (ResumableEffs i o effs a) a
action = do
        let suspMap :: ReqMap i o effs a
suspMap = Map
  (RequestID, IterationID) (i -> Eff (ResumableEffs i o effs a) a)
-> ReqMap i o effs a
forall i o (effs :: [* -> *]) a.
Map
  (RequestID, IterationID) (i -> Eff (ResumableEffs i o effs a) a)
-> ReqMap i o effs a
ReqMap Map
  (RequestID, IterationID) (i -> Eff (ResumableEffs i o effs a) a)
forall k a. Map k a
Map.empty -- start with a fresh map in every step to make sure that the old continuations are discarded

        -- handle the @ResumableEffs@ effects to get the result or
        -- the @ReqMap@ with continuations for the next response.
        (((Maybe a, IterationID), ReqMap i o effs a), Requests o)
result <- Requests o
-> Eff
     (State (Requests o) : effs)
     ((Maybe a, IterationID), ReqMap i o effs a)
-> Eff
     effs (((Maybe a, IterationID), ReqMap i o effs a), Requests o)
forall s (effs :: [* -> *]) a.
s -> Eff (State s : effs) a -> Eff effs (a, s)
runState @(Requests o) Requests o
forall a. Monoid a => a
mempty
                    (Eff
   (State (Requests o) : effs)
   ((Maybe a, IterationID), ReqMap i o effs a)
 -> Eff
      effs (((Maybe a, IterationID), ReqMap i o effs a), Requests o))
-> Eff
     (State (Requests o) : effs)
     ((Maybe a, IterationID), ReqMap i o effs a)
-> Eff
     effs (((Maybe a, IterationID), ReqMap i o effs a), Requests o)
forall a b. (a -> b) -> a -> b
$ ReqMap i o effs a
-> Eff
     (State (ReqMap i o effs a) : State (Requests o) : effs)
     (Maybe a, IterationID)
-> Eff
     (State (Requests o) : effs)
     ((Maybe a, IterationID), ReqMap i o effs a)
forall s (effs :: [* -> *]) a.
s -> Eff (State s : effs) a -> Eff effs (a, s)
runState ReqMap i o effs a
forall i o (effs :: [* -> *]) a. ReqMap i o effs a
suspMap
                    (Eff
   (State (ReqMap i o effs a) : State (Requests o) : effs)
   (Maybe a, IterationID)
 -> Eff
      (State (Requests o) : effs)
      ((Maybe a, IterationID), ReqMap i o effs a))
-> Eff
     (State (ReqMap i o effs a) : State (Requests o) : effs)
     (Maybe a, IterationID)
-> Eff
     (State (Requests o) : effs)
     ((Maybe a, IterationID), ReqMap i o effs a)
forall a b. (a -> b) -> a -> b
$ RequestID
-> Eff
     (State RequestID
        : State (ReqMap i o effs a) : State (Requests o) : effs)
     (Maybe a, IterationID)
-> Eff
     (State (ReqMap i o effs a) : State (Requests o) : effs)
     (Maybe a, IterationID)
forall s (effs :: [* -> *]) a.
s -> Eff (State s : effs) a -> Eff effs a
evalState (Natural -> RequestID
RequestID Natural
0)
                    (Eff
   (State RequestID
      : State (ReqMap i o effs a) : State (Requests o) : effs)
   (Maybe a, IterationID)
 -> Eff
      (State (ReqMap i o effs a) : State (Requests o) : effs)
      (Maybe a, IterationID))
-> Eff
     (State RequestID
        : State (ReqMap i o effs a) : State (Requests o) : effs)
     (Maybe a, IterationID)
-> Eff
     (State (ReqMap i o effs a) : State (Requests o) : effs)
     (Maybe a, IterationID)
forall a b. (a -> b) -> a -> b
$ IterationID
-> Eff
     (State IterationID
        : State RequestID : State (ReqMap i o effs a) : State (Requests o)
        : effs)
     (Maybe a)
-> Eff
     (State RequestID
        : State (ReqMap i o effs a) : State (Requests o) : effs)
     (Maybe a, IterationID)
forall s (effs :: [* -> *]) a.
s -> Eff (State s : effs) a -> Eff effs (a, s)
runState IterationID
currentIteration
                    (Eff
   (State IterationID
      : State RequestID : State (ReqMap i o effs a) : State (Requests o)
      : effs)
   (Maybe a)
 -> Eff
      (State RequestID
         : State (ReqMap i o effs a) : State (Requests o) : effs)
      (Maybe a, IterationID))
-> Eff
     (State IterationID
        : State RequestID : State (ReqMap i o effs a) : State (Requests o)
        : effs)
     (Maybe a)
-> Eff
     (State RequestID
        : State (ReqMap i o effs a) : State (Requests o) : effs)
     (Maybe a, IterationID)
forall a b. (a -> b) -> a -> b
$ forall (effs :: [* -> *]) a.
Alternative Maybe =>
Eff (NonDet : effs) a -> Eff effs (Maybe a)
forall (f :: * -> *) (effs :: [* -> *]) a.
Alternative f =>
Eff (NonDet : effs) a -> Eff effs (f a)
makeChoiceA @Maybe
                    (Eff (ResumableEffs i o effs a) a
 -> Eff
      (State IterationID
         : State RequestID : State (ReqMap i o effs a) : State (Requests o)
         : effs)
      (Maybe a))
-> Eff (ResumableEffs i o effs a) a
-> Eff
     (State IterationID
        : State RequestID : State (ReqMap i o effs a) : State (Requests o)
        : effs)
     (Maybe a)
forall a b. (a -> b) -> a -> b
$ Eff (ResumableEffs i o effs a) a
action
        case  (((Maybe a, IterationID), ReqMap i o effs a), Requests o)
result of
            (((Maybe a
Nothing, IterationID
it), ReqMap Map
  (RequestID, IterationID) (i -> Eff (ResumableEffs i o effs a) a)
mp), Requests o
rqs) ->
                let k :: Response i -> Eff effs (Maybe (MultiRequestContStatus i o effs a))
k Response{RequestID
rspRqID :: RequestID
rspRqID :: forall i. Response i -> RequestID
rspRqID, IterationID
rspItID :: IterationID
rspItID :: forall i. Response i -> IterationID
rspItID, i
rspResponse :: i
rspResponse :: forall i. Response i -> i
rspResponse} = do
                        case (RequestID, IterationID)
-> Map
     (RequestID, IterationID) (i -> Eff (ResumableEffs i o effs a) a)
-> Maybe (i -> Eff (ResumableEffs i o effs a) a)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (RequestID
rspRqID, IterationID
rspItID) Map
  (RequestID, IterationID) (i -> Eff (ResumableEffs i o effs a) a)
mp of
                            Maybe (i -> Eff (ResumableEffs i o effs a) a)
Nothing -> Maybe (MultiRequestContStatus i o effs a)
-> Eff effs (Maybe (MultiRequestContStatus i o effs a))
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (MultiRequestContStatus i o effs a)
forall a. Maybe a
Nothing
                            Just i -> Eff (ResumableEffs i o effs a) a
k' -> do
                                let nextIteration :: IterationID
nextIteration = IterationID -> IterationID
forall a. Enum a => a -> a
succ IterationID
it
                                IterationID
-> Eff (ResumableEffs i o effs a) a
-> Eff effs (Maybe (MultiRequestContStatus i o effs a))
go IterationID
nextIteration (i -> Eff (ResumableEffs i o effs a) a
k' i
rspResponse)
                in Maybe (MultiRequestContStatus i o effs a)
-> Eff effs (Maybe (MultiRequestContStatus i o effs a))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe (MultiRequestContStatus i o effs a)
 -> Eff effs (Maybe (MultiRequestContStatus i o effs a)))
-> Maybe (MultiRequestContStatus i o effs a)
-> Eff effs (Maybe (MultiRequestContStatus i o effs a))
forall a b. (a -> b) -> a -> b
$ MultiRequestContStatus i o effs a
-> Maybe (MultiRequestContStatus i o effs a)
forall a. a -> Maybe a
Just (MultiRequestContStatus i o effs a
 -> Maybe (MultiRequestContStatus i o effs a))
-> MultiRequestContStatus i o effs a
-> Maybe (MultiRequestContStatus i o effs a)
forall a b. (a -> b) -> a -> b
$ MultiRequestContinuation i o effs a
-> MultiRequestContStatus i o effs a
forall i o (effs :: [* -> *]) a.
MultiRequestContinuation i o effs a
-> MultiRequestContStatus i o effs a
AContinuation (MultiRequestContinuation i o effs a
 -> MultiRequestContStatus i o effs a)
-> MultiRequestContinuation i o effs a
-> MultiRequestContStatus i o effs a
forall a b. (a -> b) -> a -> b
$ MultiRequestContinuation :: forall i o (effs :: [* -> *]) a.
(Response i
 -> Eff effs (Maybe (MultiRequestContStatus i o effs a)))
-> Requests o -> MultiRequestContinuation i o effs a
MultiRequestContinuation { ndcCont :: Response i -> Eff effs (Maybe (MultiRequestContStatus i o effs a))
ndcCont = Response i -> Eff effs (Maybe (MultiRequestContStatus i o effs a))
k, ndcRequests :: Requests o
ndcRequests = Requests o
rqs}
            (((Just a
a, IterationID
_), ReqMap i o effs a
_), Requests o
_) -> Maybe (MultiRequestContStatus i o effs a)
-> Eff effs (Maybe (MultiRequestContStatus i o effs a))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe (MultiRequestContStatus i o effs a)
 -> Eff effs (Maybe (MultiRequestContStatus i o effs a)))
-> Maybe (MultiRequestContStatus i o effs a)
-> Eff effs (Maybe (MultiRequestContStatus i o effs a))
forall a b. (a -> b) -> a -> b
$ MultiRequestContStatus i o effs a
-> Maybe (MultiRequestContStatus i o effs a)
forall a. a -> Maybe a
Just (MultiRequestContStatus i o effs a
 -> Maybe (MultiRequestContStatus i o effs a))
-> MultiRequestContStatus i o effs a
-> Maybe (MultiRequestContStatus i o effs a)
forall a b. (a -> b) -> a -> b
$ a -> MultiRequestContStatus i o effs a
forall i o (effs :: [* -> *]) a.
a -> MultiRequestContStatus i o effs a
AResult a
a

-- | Given the status of a suspended computation, either
--   return the result or record the request and store
--   the continuation in the 'ReqMap'
runStep ::
    forall i o a effs.
    Status (ResumableEffs i o effs a) o i a
    -> Eff (ResumableEffs i o effs a) a
runStep :: Status (ResumableEffs i o effs a) o i a
-> Eff (ResumableEffs i o effs a) a
runStep = \case
    Done a
a -> a -> Eff (ResumableEffs i o effs a) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a

    -- We have reached a point where we need more input.
    Continue o
o i
-> Eff
     (ResumableEffs i o effs a)
     (Status (ResumableEffs i o effs a) o i a)
k -> do

        -- Store the request @o@ and get the keys identifying it
        (IterationID
iid,RequestID
nid) <- o -> Eff (ResumableEffs i o effs a) (IterationID, RequestID)
forall o (effs :: [* -> *]).
(Member (State (Requests o)) effs, Member (State IterationID) effs,
 Member (State RequestID) effs) =>
o -> Eff effs (IterationID, RequestID)
nextRequestID o
o

        let onResponse :: i -> Eff (ResumableEffs i o effs a) a
onResponse i
i = do
                -- when we get a response @i@, we

                -- clear the requests,
                forall (effs :: [* -> *]).
Member (State (Requests o)) effs =>
Eff effs ()
forall o (effs :: [* -> *]).
Member (State (Requests o)) effs =>
Eff effs ()
clearRequests @o

                -- compute the next 'Status'
                Status (ResumableEffs i o effs a) o i a
status :: Status (ResumableEffs i o effs a) o i a <- i
-> Eff
     (ResumableEffs i o effs a)
     (Status (ResumableEffs i o effs a) o i a)
k i
i

                -- repeat
                Status (ResumableEffs i o effs a) o i a
-> Eff (ResumableEffs i o effs a) a
forall i o a (effs :: [* -> *]).
Status (ResumableEffs i o effs a) o i a
-> Eff (ResumableEffs i o effs a) a
runStep Status (ResumableEffs i o effs a) o i a
status

        (ReqMap i o effs a -> ReqMap i o effs a)
-> Eff (ResumableEffs i o effs a) ()
forall s (effs :: [* -> *]).
Member (State s) effs =>
(s -> s) -> Eff effs ()
modify @(ReqMap i o effs a) ((RequestID, IterationID)
-> (i -> Eff (ResumableEffs i o effs a) a)
-> ReqMap i o effs a
-> ReqMap i o effs a
forall i o (effs :: [* -> *]) a.
(RequestID, IterationID)
-> (i -> Eff (ResumableEffs i o effs a) a)
-> ReqMap i o effs a
-> ReqMap i o effs a
insertRequest (RequestID
nid, IterationID
iid) i -> Eff (ResumableEffs i o effs a) a
onResponse)

        -- Stop evaluating this branch. We can resume it later by running
        -- the continuation associated with @(iid, nid)@ in the @ReqMap@.
        Eff (ResumableEffs i o effs a) a
forall (f :: * -> *) a. Alternative f => f a
empty

-- | Interpret 'Yield' as a prompt-type effect using 'NonDet' to
--   branch out and choose a branch, and the 'State' effects to
--   keep track of request IDs.
suspendNonDet ::
    forall i o a effs.
    Eff (Yield o i ': ResumableEffs i o effs a) a
    -> Eff effs (Maybe (MultiRequestContStatus i o effs a))
suspendNonDet :: Eff (Yield o i : ResumableEffs i o effs a) a
-> Eff effs (Maybe (MultiRequestContStatus i o effs a))
suspendNonDet Eff (Yield o i : ResumableEffs i o effs a) a
e = Eff (ResumableEffs i o effs a) a
-> Eff effs (Maybe (MultiRequestContStatus i o effs a))
forall i o a (effs :: [* -> *]).
Eff (ResumableEffs i o effs a) a
-> Eff effs (Maybe (MultiRequestContStatus i o effs a))
runSuspInt (Eff (Yield o i : ResumableEffs i o effs a) a
-> Eff
     (ResumableEffs i o effs a)
     (Status (ResumableEffs i o effs a) o i a)
forall a b (effs :: [* -> *]) r.
Eff (Yield a b : effs) r -> Eff effs (Status effs a b r)
runC Eff (Yield o i : ResumableEffs i o effs a) a
e Eff
  (ResumableEffs i o effs a)
  (Status (ResumableEffs i o effs a) o i a)
-> (Status (ResumableEffs i o effs a) o i a
    -> Eff (ResumableEffs i o effs a) a)
-> Eff (ResumableEffs i o effs a) a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Status (ResumableEffs i o effs a) o i a
-> Eff (ResumableEffs i o effs a) a
forall i o a (effs :: [* -> *]).
Status (ResumableEffs i o effs a) o i a
-> Eff (ResumableEffs i o effs a) a
runStep)

insertResponse :: Response i -> Responses i -> Responses i
insertResponse :: Response i -> Responses i -> Responses i
insertResponse Response{RequestID
rspRqID :: RequestID
rspRqID :: forall i. Response i -> RequestID
rspRqID,IterationID
rspItID :: IterationID
rspItID :: forall i. Response i -> IterationID
rspItID,i
rspResponse :: i
rspResponse :: forall i. Response i -> i
rspResponse} (Responses Map (IterationID, RequestID) i
r) =
    Map (IterationID, RequestID) i -> Responses i
forall i. Map (IterationID, RequestID) i -> Responses i
Responses (Map (IterationID, RequestID) i -> Responses i)
-> Map (IterationID, RequestID) i -> Responses i
forall a b. (a -> b) -> a -> b
$ (IterationID, RequestID)
-> i
-> Map (IterationID, RequestID) i
-> Map (IterationID, RequestID) i
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert (IterationID
rspItID, RequestID
rspRqID) i
rspResponse Map (IterationID, RequestID) i
r


-- Generate a pair of 'RequestID' and 'IterationID' for
-- the given request @o@. It writes the request, to the
-- 'Requests' state alongside the two identifiers.
nextRequestID ::
    ( Member (State (Requests o)) effs
    , Member (State IterationID) effs
    , Member (State RequestID) effs
    )
    => o
    -> Eff effs (IterationID, RequestID)
nextRequestID :: o -> Eff effs (IterationID, RequestID)
nextRequestID o
s = do
    Requests{[Request o]
unRequests :: [Request o]
unRequests :: forall o. Requests o -> [Request o]
unRequests} <- Eff effs (Requests o)
forall s (effs :: [* -> *]). Member (State s) effs => Eff effs s
get
    RequestID
requestID <- forall (effs :: [* -> *]).
Member (State RequestID) effs =>
Eff effs RequestID
forall s (effs :: [* -> *]). Member (State s) effs => Eff effs s
get @RequestID
    IterationID
iid <- forall (effs :: [* -> *]).
Member (State IterationID) effs =>
Eff effs IterationID
forall s (effs :: [* -> *]). Member (State s) effs => Eff effs s
get @IterationID
    let nid :: RequestID
nid  = RequestID -> RequestID
forall a. Enum a => a -> a
succ RequestID
requestID
    Requests o -> Eff effs ()
forall s (effs :: [* -> *]).
Member (State s) effs =>
s -> Eff effs ()
put (Requests o -> Eff effs ()) -> Requests o -> Eff effs ()
forall a b. (a -> b) -> a -> b
$ Requests :: forall o. [Request o] -> Requests o
Requests
            { unRequests :: [Request o]
unRequests = Request :: forall o. RequestID -> IterationID -> o -> Request o
Request{rqRequest :: o
rqRequest=o
s,rqID :: RequestID
rqID=RequestID
nid,itID :: IterationID
itID=IterationID
iid} Request o -> [Request o] -> [Request o]
forall a. a -> [a] -> [a]
: [Request o]
unRequests
            }
    RequestID -> Eff effs ()
forall s (effs :: [* -> *]).
Member (State s) effs =>
s -> Eff effs ()
put RequestID
nid
    (IterationID, RequestID) -> Eff effs (IterationID, RequestID)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (IterationID
iid, RequestID
nid)

clearRequests :: forall o effs. Member (State (Requests o)) effs => Eff effs ()
clearRequests :: Eff effs ()
clearRequests = (Requests o -> Requests o) -> Eff effs ()
forall s (effs :: [* -> *]).
Member (State s) effs =>
(s -> s) -> Eff effs ()
modify @(Requests o) (\Requests o
rq -> Requests o
rq{unRequests :: [Request o]
unRequests = [] })