{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Test.Consensus.PointSchedule.SinglePeer.Indices (
HeaderPointSchedule (..)
, headerPointSchedule
, rollbacksTipPoints
, singleJumpTipPoints
, tipPointSchedule
, uniformRMDiffTime
) where
import Control.Monad (forM, replicateM)
import Control.Monad.Class.MonadTime.SI (Time (Time), addTime)
import Data.List (sort)
import Data.Time.Clock (DiffTime, diffTimeToPicoseconds,
picosecondsToDiffTime)
import GHC.Stack (HasCallStack)
import Ouroboros.Network.Block (SlotNo (SlotNo))
import qualified System.Random.Stateful as R
singleJumpTipPoints :: R.StatefulGen g m => g -> Int -> Int -> m [Int]
singleJumpTipPoints :: forall g (m :: * -> *).
StatefulGen g m =>
g -> Int -> Int -> m [Int]
singleJumpTipPoints g
_g Int
m Int
n
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
m = [Int] -> m [Int]
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
singleJumpTipPoints g
g Int
m Int
n = do
Int
jump <- (Int, Int) -> g -> m Int
forall a g (m :: * -> *).
(UniformRange a, StatefulGen g m) =>
(a, a) -> g -> m a
forall g (m :: * -> *). StatefulGen g m => (Int, Int) -> g -> m Int
R.uniformRM (Int
m, Int
n) g
g
[Int] -> m [Int]
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Int
jump..Int
n]
rollbacksTipPoints
:: R.StatefulGen g m => g -> Int -> [Int] -> m [[Int]]
rollbacksTipPoints :: forall g (m :: * -> *).
StatefulGen g m =>
g -> Int -> [Int] -> m [[Int]]
rollbacksTipPoints g
g Int
k = (Int -> m [Int]) -> [Int] -> m [[Int]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Int -> m [Int]
forall {m :: * -> *}. StatefulGen g m => Int -> m [Int]
walkBranch
where
walkBranch :: Int -> m [Int]
walkBranch Int
bn = g -> Int -> Int -> m [Int]
forall g (m :: * -> *).
StatefulGen g m =>
g -> Int -> Int -> m [Int]
singleJumpTipPoints g
g Int
0 (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min (Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) (Int
bn Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1))
tipPointSchedule
:: forall g m. R.StatefulGen g m => g -> DiffTime -> (DiffTime, DiffTime) -> [SlotNo] -> m [Time]
tipPointSchedule :: forall g (m :: * -> *).
StatefulGen g m =>
g -> DiffTime -> (DiffTime, DiffTime) -> [SlotNo] -> m [Time]
tipPointSchedule g
_g DiffTime
slotLength (DiffTime
a, DiffTime
b) [SlotNo]
_slots
| DiffTime
slotLength DiffTime -> DiffTime -> Bool
forall a. Ord a => a -> a -> Bool
<= DiffTime
b = [Char] -> m [Time]
forall a. HasCallStack => [Char] -> a
error [Char]
"tipPointSchedule: slotLength <= maximum delay"
| DiffTime
b DiffTime -> DiffTime -> Bool
forall a. Ord a => a -> a -> Bool
< DiffTime
a = [Char] -> m [Time]
forall a. HasCallStack => [Char] -> a
error [Char]
"tipPointSchedule: empty delay interval"
tipPointSchedule g
g DiffTime
slotLength (DiffTime, DiffTime)
msgDelayInterval [SlotNo]
slots = do
let
slotTimes :: [Time]
slotTimes = (SlotNo -> Time) -> [SlotNo] -> [Time]
forall a b. (a -> b) -> [a] -> [b]
map SlotNo -> Time
slotTime [SlotNo]
slots
timePairs :: [(Time, Time)]
timePairs = [Time] -> [Time] -> [(Time, Time)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Time]
slotTimes ([Time] -> [(Time, Time)]) -> [Time] -> [(Time, Time)]
forall a b. (a -> b) -> a -> b
$ (Int -> [Time] -> [Time]
forall a. Int -> [a] -> [a]
drop Int
1 [Time]
slotTimes) [Time] -> [Time] -> [Time]
forall a. [a] -> [a] -> [a]
++ [DiffTime -> Time -> Time
addTime DiffTime
1 ([Time] -> Time
forall a. HasCallStack => [a] -> a
last [Time]
slotTimes)]
[(Time, Time)] -> m [Time]
go [(Time, Time)]
timePairs
where
go :: [(Time, Time)] -> m [Time]
go :: [(Time, Time)] -> m [Time]
go [] = [Time] -> m [Time]
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
go [(Time, Time)]
xs = do
let ([(Time, Time)]
pointSeq, [(Time, Time)]
newBranch) = ((Time, Time) -> Bool)
-> [(Time, Time)] -> ([(Time, Time)], [(Time, Time)])
forall a. (a -> Bool) -> [a] -> ([a], [a])
span (\(Time
a, Time
b) -> Time
a Time -> Time -> Bool
forall a. Ord a => a -> a -> Bool
< Time
b) [(Time, Time)]
xs
[Time]
times <- [(Time, Time)] -> ((Time, Time) -> m Time) -> m [Time]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [(Time, Time)]
pointSeq (((Time, Time) -> m Time) -> m [Time])
-> ((Time, Time) -> m Time) -> m [Time]
forall a b. (a -> b) -> a -> b
$ \(Time
s, Time
_) -> do
DiffTime
delay <- (DiffTime, DiffTime) -> g -> m DiffTime
forall g (m :: * -> *).
StatefulGen g m =>
(DiffTime, DiffTime) -> g -> m DiffTime
uniformRMDiffTime (DiffTime, DiffTime)
msgDelayInterval g
g
Time -> m Time
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Time -> m Time) -> Time -> m Time
forall a b. (a -> b) -> a -> b
$ DiffTime -> Time -> Time
addTime DiffTime
delay Time
s
([Time]
times', [(Time, Time)]
xss) <- case [(Time, Time)]
newBranch of
[] -> ([Time], [(Time, Time)]) -> m ([Time], [(Time, Time)])
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([], [])
((Time
seqLast, Time
_) : [(Time, Time)]
branches) -> do
DiffTime
delay <- (DiffTime, DiffTime) -> g -> m DiffTime
forall g (m :: * -> *).
StatefulGen g m =>
(DiffTime, DiffTime) -> g -> m DiffTime
uniformRMDiffTime (DiffTime, DiffTime)
msgDelayInterval g
g
let lastTime :: Time
lastTime = DiffTime -> Time -> Time
addTime DiffTime
delay Time
seqLast
([Time]
times', [(Time, Time)]
xss) <- Time -> [(Time, Time)] -> m ([Time], [(Time, Time)])
handleDelayedTipPoints Time
lastTime [(Time, Time)]
branches
([Time], [(Time, Time)]) -> m ([Time], [(Time, Time)])
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Time
lastTime Time -> [Time] -> [Time]
forall a. a -> [a] -> [a]
: [Time]
times', [(Time, Time)]
xss)
[Time]
times'' <- [(Time, Time)] -> m [Time]
go [(Time, Time)]
xss
[Time] -> m [Time]
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Time] -> m [Time]) -> [Time] -> m [Time]
forall a b. (a -> b) -> a -> b
$ [Time]
times [Time] -> [Time] -> [Time]
forall a. [a] -> [a] -> [a]
++ [Time]
times' [Time] -> [Time] -> [Time]
forall a. [a] -> [a] -> [a]
++ [Time]
times''
slotsDiffTime :: Int -> DiffTime
slotsDiffTime :: Int -> DiffTime
slotsDiffTime Int
s = Int -> DiffTime
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s DiffTime -> DiffTime -> DiffTime
forall a. Num a => a -> a -> a
* DiffTime
slotLength
slotTime :: SlotNo -> Time
slotTime :: SlotNo -> Time
slotTime (SlotNo Word64
s) = DiffTime -> Time
Time (Int -> DiffTime
slotsDiffTime (Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
s))
handleDelayedTipPoints :: Time -> [(Time, Time)] -> m ([Time], [(Time, Time)])
handleDelayedTipPoints :: Time -> [(Time, Time)] -> m ([Time], [(Time, Time)])
handleDelayedTipPoints Time
lastTime [(Time, Time)]
xss = do
let ([(Time, Time)]
pointSeq, [(Time, Time)]
newBranch) = ((Time, Time) -> Bool)
-> [(Time, Time)] -> ([(Time, Time)], [(Time, Time)])
forall a. (a -> Bool) -> [a] -> ([a], [a])
span (\(Time
a, Time
_) -> DiffTime -> Time -> Time
addTime ((DiffTime, DiffTime) -> DiffTime
forall a b. (a, b) -> a
fst (DiffTime, DiffTime)
msgDelayInterval) Time
a Time -> Time -> Bool
forall a. Ord a => a -> a -> Bool
<= Time
lastTime) [(Time, Time)]
xss
nseq :: Int
nseq = [(Time, Time)] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Time, Time)]
pointSeq
firstLater :: Time
firstLater = case [(Time, Time)]
newBranch of
[] -> DiffTime -> Time -> Time
addTime (Int -> DiffTime
slotsDiffTime (Int -> Int
forall a. Enum a => Int -> a
toEnum Int
nseq)) Time
lastTime
((Time
a, Time
_) : [(Time, Time)]
_) -> DiffTime -> Time -> Time
addTime ((DiffTime, DiffTime) -> DiffTime
forall a b. (a, b) -> a
fst (DiffTime, DiffTime)
msgDelayInterval) Time
a
[Time]
times <- Int -> m Time -> m [Time]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
nseq ((Time, Time) -> g -> m Time
forall g (m :: * -> *).
StatefulGen g m =>
(Time, Time) -> g -> m Time
uniformRMTime (Time
lastTime, Time
firstLater) g
g)
([Time], [(Time, Time)]) -> m ([Time], [(Time, Time)])
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Time] -> [Time]
forall a. Ord a => [a] -> [a]
sort [Time]
times, [(Time, Time)]
newBranch)
uniformRMDiffTime :: R.StatefulGen g m => (DiffTime, DiffTime) -> g -> m DiffTime
uniformRMDiffTime :: forall g (m :: * -> *).
StatefulGen g m =>
(DiffTime, DiffTime) -> g -> m DiffTime
uniformRMDiffTime (DiffTime
a, DiffTime
b) g
g =
Integer -> DiffTime
picosecondsToDiffTime (Integer -> DiffTime) -> m Integer -> m DiffTime
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
(Integer, Integer) -> g -> m Integer
forall a g (m :: * -> *).
(UniformRange a, StatefulGen g m) =>
(a, a) -> g -> m a
forall g (m :: * -> *).
StatefulGen g m =>
(Integer, Integer) -> g -> m Integer
R.uniformRM (DiffTime -> Integer
diffTimeToPicoseconds DiffTime
a, DiffTime -> Integer
diffTimeToPicoseconds DiffTime
b) g
g
uniformRMTime :: R.StatefulGen g m => (Time, Time) -> g -> m Time
uniformRMTime :: forall g (m :: * -> *).
StatefulGen g m =>
(Time, Time) -> g -> m Time
uniformRMTime (Time DiffTime
a, Time DiffTime
b) g
g = DiffTime -> Time
Time (DiffTime -> Time) -> m DiffTime -> m Time
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (DiffTime, DiffTime) -> g -> m DiffTime
forall g (m :: * -> *).
StatefulGen g m =>
(DiffTime, DiffTime) -> g -> m DiffTime
uniformRMDiffTime (DiffTime
a, DiffTime
b) g
g
data = {
HeaderPointSchedule -> [(Time, Int)]
hpsTrunk :: [(Time, Int)]
, HeaderPointSchedule -> [(Time, Int)]
hpsBranch :: [(Time, Int)]
}
deriving (Int -> HeaderPointSchedule -> ShowS
[HeaderPointSchedule] -> ShowS
HeaderPointSchedule -> [Char]
(Int -> HeaderPointSchedule -> ShowS)
-> (HeaderPointSchedule -> [Char])
-> ([HeaderPointSchedule] -> ShowS)
-> Show HeaderPointSchedule
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> HeaderPointSchedule -> ShowS
showsPrec :: Int -> HeaderPointSchedule -> ShowS
$cshow :: HeaderPointSchedule -> [Char]
show :: HeaderPointSchedule -> [Char]
$cshowList :: [HeaderPointSchedule] -> ShowS
showList :: [HeaderPointSchedule] -> ShowS
Show)
headerPointSchedule
:: forall g m. (HasCallStack, R.StatefulGen g m)
=> g
-> (DiffTime, DiffTime)
-> [(Maybe Int, [(Time, Int)])]
-> m [HeaderPointSchedule]
g
g (DiffTime, DiffTime)
msgDelayInterval [(Maybe Int, [(Time, Int)])]
xs =
let
xs' :: [((Maybe Int, [(Time, Int)]), Maybe Time)]
xs' = [(Maybe Int, [(Time, Int)])]
-> [Maybe Time] -> [((Maybe Int, [(Time, Int)]), Maybe Time)]
forall a b. [a] -> [b] -> [(a, b)]
zip [(Maybe Int, [(Time, Int)])]
xs ([Maybe Time] -> [((Maybe Int, [(Time, Int)]), Maybe Time)])
-> [Maybe Time] -> [((Maybe Int, [(Time, Int)]), Maybe Time)]
forall a b. (a -> b) -> a -> b
$ ((Maybe Int, [(Time, Int)]) -> Maybe Time)
-> [(Maybe Int, [(Time, Int)])] -> [Maybe Time]
forall a b. (a -> b) -> [a] -> [b]
map (Time -> Maybe Time
forall a. a -> Maybe a
Just (Time -> Maybe Time)
-> ((Maybe Int, [(Time, Int)]) -> Time)
-> (Maybe Int, [(Time, Int)])
-> Maybe Time
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Time, Int) -> Time
forall a b. (a, b) -> a
fst ((Time, Int) -> Time)
-> ((Maybe Int, [(Time, Int)]) -> (Time, Int))
-> (Maybe Int, [(Time, Int)])
-> Time
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(Time, Int)] -> (Time, Int)
forall a. HasCallStack => [a] -> a
headCallStack ([(Time, Int)] -> (Time, Int))
-> ((Maybe Int, [(Time, Int)]) -> [(Time, Int)])
-> (Maybe Int, [(Time, Int)])
-> (Time, Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe Int, [(Time, Int)]) -> [(Time, Int)]
forall a b. (a, b) -> b
snd) (Int -> [(Maybe Int, [(Time, Int)])] -> [(Maybe Int, [(Time, Int)])]
forall a. Int -> [a] -> [a]
drop Int
1 [(Maybe Int, [(Time, Int)])]
xs) [Maybe Time] -> [Maybe Time] -> [Maybe Time]
forall a. [a] -> [a] -> [a]
++ [Maybe Time
forall a. Maybe a
Nothing]
in ((Time, Int), [HeaderPointSchedule]) -> [HeaderPointSchedule]
forall a b. (a, b) -> b
snd (((Time, Int), [HeaderPointSchedule]) -> [HeaderPointSchedule])
-> m ((Time, Int), [HeaderPointSchedule])
-> m [HeaderPointSchedule]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Time, Int)
-> ((Maybe Int, [(Time, Int)]), Maybe Time)
-> m ((Time, Int), HeaderPointSchedule))
-> (Time, Int)
-> [((Maybe Int, [(Time, Int)]), Maybe Time)]
-> m ((Time, Int), [HeaderPointSchedule])
forall (m :: * -> *) s x y.
Monad m =>
(s -> x -> m (s, y)) -> s -> [x] -> m (s, [y])
mapAccumM (Time, Int)
-> ((Maybe Int, [(Time, Int)]), Maybe Time)
-> m ((Time, Int), HeaderPointSchedule)
genHPBranchSchedule (DiffTime -> Time
Time DiffTime
0, Int
0) [((Maybe Int, [(Time, Int)]), Maybe Time)]
xs'
where
genHPBranchSchedule
:: (Time, Int)
-> ((Maybe Int, [(Time, Int)]), Maybe Time)
-> m ((Time, Int), HeaderPointSchedule)
genHPBranchSchedule :: (Time, Int)
-> ((Maybe Int, [(Time, Int)]), Maybe Time)
-> m ((Time, Int), HeaderPointSchedule)
genHPBranchSchedule (Time
tNext, Int
trunkNextHp) ((Maybe Int
_mi, []), Maybe Time
_mtMax) =
((Time, Int), HeaderPointSchedule)
-> m ((Time, Int), HeaderPointSchedule)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((Time
tNext, Int
trunkNextHp), [(Time, Int)] -> [(Time, Int)] -> HeaderPointSchedule
HeaderPointSchedule [] [])
genHPBranchSchedule (Time
tNext, Int
trunkNextHp) ((Maybe Int
Nothing, [(Time, Int)]
tps), Maybe Time
mtMax) = do
((Time, Int)
p, [[(Time, Int)]]
tsTrunk) <- ((Time, Int) -> (Time, Int) -> m ((Time, Int), [(Time, Int)]))
-> (Time, Int) -> [(Time, Int)] -> m ((Time, Int), [[(Time, Int)]])
forall (m :: * -> *) s x y.
Monad m =>
(s -> x -> m (s, y)) -> s -> [x] -> m (s, [y])
mapAccumM (Maybe Time
-> (Time, Int) -> (Time, Int) -> m ((Time, Int), [(Time, Int)])
generatePerTipPointTimes Maybe Time
mtMax) (Time
tNext, Int
trunkNextHp) [(Time, Int)]
tps
((Time, Int), HeaderPointSchedule)
-> m ((Time, Int), HeaderPointSchedule)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((Time, Int)
p, [(Time, Int)] -> [(Time, Int)] -> HeaderPointSchedule
HeaderPointSchedule ([[(Time, Int)]] -> [(Time, Int)]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[(Time, Int)]]
tsTrunk) [])
genHPBranchSchedule (Time
tNext, Int
trunkNextHp) ((Just Int
iLast, tps :: [(Time, Int)]
tps@((Time
firstTipTime, Int
_):[(Time, Int)]
_)), Maybe Time
mtMax) = do
((Time
tNext', Int
trunkNextHp'), [(Time, Int)]
tsTrunk) <- Maybe Time
-> (Time, Int) -> (Time, Int) -> m ((Time, Int), [(Time, Int)])
generatePerTipPointTimes Maybe Time
mtMax (Time
tNext, Int
trunkNextHp) (Time
firstTipTime, Int
iLast)
((Time
tNext'', Int
_), [[(Time, Int)]]
tsBranch) <- ((Time, Int) -> (Time, Int) -> m ((Time, Int), [(Time, Int)]))
-> (Time, Int) -> [(Time, Int)] -> m ((Time, Int), [[(Time, Int)]])
forall (m :: * -> *) s x y.
Monad m =>
(s -> x -> m (s, y)) -> s -> [x] -> m (s, [y])
mapAccumM (Maybe Time
-> (Time, Int) -> (Time, Int) -> m ((Time, Int), [(Time, Int)])
generatePerTipPointTimes Maybe Time
mtMax) (Time
tNext', Int
0) [(Time, Int)]
tps
((Time, Int), HeaderPointSchedule)
-> m ((Time, Int), HeaderPointSchedule)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((Time
tNext'', Int
trunkNextHp'), [(Time, Int)] -> [(Time, Int)] -> HeaderPointSchedule
HeaderPointSchedule [(Time, Int)]
tsTrunk ([[(Time, Int)]] -> [(Time, Int)]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[(Time, Int)]]
tsBranch))
generatePerTipPointTimes
:: Maybe Time
-> (Time, Int)
-> (Time, Int)
-> m ((Time, Int), [(Time, Int)])
generatePerTipPointTimes :: Maybe Time
-> (Time, Int) -> (Time, Int) -> m ((Time, Int), [(Time, Int)])
generatePerTipPointTimes Maybe Time
mtMax (Time
tNext0, Int
nextHp0) (Time
tTip, Int
tp) = do
DiffTime
t <- (DiffTime, DiffTime) -> g -> m DiffTime
forall g (m :: * -> *).
StatefulGen g m =>
(DiffTime, DiffTime) -> g -> m DiffTime
uniformRMDiffTime (DiffTime, DiffTime)
msgDelayInterval g
g
Time -> Int -> [(Time, Int)] -> m ((Time, Int), [(Time, Int)])
go (Time -> Time -> Time
forall a. Ord a => a -> a -> a
max Time
tNext0 (DiffTime -> Time -> Time
addTime DiffTime
t Time
tTip)) Int
nextHp0 []
where
go :: Time -> Int -> [(Time, Int)] -> m ((Time, Int), [(Time, Int)])
go :: Time -> Int -> [(Time, Int)] -> m ((Time, Int), [(Time, Int)])
go Time
tNext Int
nextHp [(Time, Int)]
acc = do
if Bool -> (Time -> Bool) -> Maybe Time -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
False (Time
tNext Time -> Time -> Bool
forall a. Ord a => a -> a -> Bool
>) Maybe Time
mtMax Bool -> Bool -> Bool
|| Int
nextHp Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
tp then
((Time, Int), [(Time, Int)]) -> m ((Time, Int), [(Time, Int)])
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((Time
tNext, Int
nextHp), [(Time, Int)] -> [(Time, Int)]
forall a. [a] -> [a]
reverse [(Time, Int)]
acc)
else do
Time
t <- (DiffTime -> Time -> Time
`addTime` Time
tNext) (DiffTime -> Time) -> m DiffTime -> m Time
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (DiffTime, DiffTime) -> g -> m DiffTime
forall g (m :: * -> *).
StatefulGen g m =>
(DiffTime, DiffTime) -> g -> m DiffTime
uniformRMDiffTime (DiffTime, DiffTime)
msgDelayInterval g
g
Time -> Int -> [(Time, Int)] -> m ((Time, Int), [(Time, Int)])
go Time
t (Int
nextHpInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) ((Time
tNext, Int
nextHp) (Time, Int) -> [(Time, Int)] -> [(Time, Int)]
forall a. a -> [a] -> [a]
: [(Time, Int)]
acc)
mapAccumM :: Monad m => (s -> x -> m (s, y)) -> s -> [x] -> m (s, [y])
mapAccumM :: forall (m :: * -> *) s x y.
Monad m =>
(s -> x -> m (s, y)) -> s -> [x] -> m (s, [y])
mapAccumM s -> x -> m (s, y)
_ s
acc [] = (s, [y]) -> m (s, [y])
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (s
acc, [])
mapAccumM s -> x -> m (s, y)
f s
acc (x
x:[x]
xs) = do
(s
acc', y
y) <- s -> x -> m (s, y)
f s
acc x
x
(s
acc'', [y]
ys) <- (s -> x -> m (s, y)) -> s -> [x] -> m (s, [y])
forall (m :: * -> *) s x y.
Monad m =>
(s -> x -> m (s, y)) -> s -> [x] -> m (s, [y])
mapAccumM s -> x -> m (s, y)
f s
acc' [x]
xs
(s, [y]) -> m (s, [y])
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (s
acc'', y
yy -> [y] -> [y]
forall a. a -> [a] -> [a]
:[y]
ys)
headCallStack :: HasCallStack => [a] -> a
headCallStack :: forall a. HasCallStack => [a] -> a
headCallStack = \case
a
x:[a]
_ -> a
x
[a]
_ -> [Char] -> a
forall a. HasCallStack => [Char] -> a
error [Char]
"headCallStack: empty list"