{-# LANGUAGE ImportQualifiedPost #-} {-# LANGUAGE BlockArguments, LambdaCase #-} {-# LANGUAGE ExplicitForAll #-} {-# LANGUAGE RequiredTypeArguments #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# OPTIONS_GHC -Wall -fno-warn-tabs #-} module Control.Monad.Yaftee.Pipe.MonoTraversable ( lengthRun, length, length', Length, lengthFromInt64, lengthToInt64 ) where import Prelude hiding (length) import Control.Monad import Control.Monad.Fix import Control.Monad.Yaftee.Eff qualified as Eff import Control.Monad.Yaftee.Pipe qualified as Pipe import Control.Monad.Yaftee.State qualified as State import Control.HigherOpenUnion qualified as U import Data.HigherFunctor qualified as HFunctor import Data.MonoTraversable import Data.Int lengthRun :: forall nm es i o r . HFunctor.Loose (U.U es) => Eff.E (State.Named nm Length ': es) i o r -> Eff.E es i o (r, Length) lengthRun = (`State.runN` (0 :: Length)) length :: forall nm -> ( MonoFoldable mono, U.Member Pipe.P es, U.Member (State.Named nm Length) es ) => Eff.E es mono mono r length nm = do State.putN nm $ Length 0 forever $ Pipe.await >>= \xs -> State.modifyN nm (+ Length (olength64 xs)) >> Pipe.yield xs length' :: forall nm -> ( MonoFoldable mono, U.Member Pipe.P es, U.Member (State.Named nm Length) es ) => Eff.E es mono mono () length' nm = do State.putN nm $ Length 0 fix \go -> Pipe.awaitMaybe >>= \case Nothing -> pure () Just xs -> (>> go) do State.modifyN nm (+ Length (olength64 xs)) Pipe.yield xs newtype Length = Length { unLength :: Int64 } deriving (Show, Eq, Ord, Enum, Num, Real, Integral) lengthToInt64 :: Length -> Int64 lengthToInt64 = unLength lengthFromInt64 :: Int64 -> Length lengthFromInt64 = Length