polysemy-scoped-fs-0.1.0.0: src/Polysemy/SequentialAccess.hs
{-|
Copyright : (c) Hisaket VioletRed, 2022
License : AGPL-3.0-or-later
Maintainer : hisaket@outlook.jp
Stability : experimental
Portability : POSIX
-}
module Polysemy.SequentialAccess where
import Polysemy ( Member, Sem, interpret, makeSem )
import Prelude hiding ( Read, read )
import Polysemy.Input ( Input (Input) )
import Polysemy.Output ( Output (Output) )
data GetPosition pos m a where
GetPosition :: GetPosition pos m pos
{- ^An effect that gets the current cursor position in the file.
-}
makeSem ''GetPosition
{- |A type that represents both ends or intermediate positions in the file.
-}
data TriPosition = End Ends | Intermediate
deriving (Eq, Ord, Show)
{- |A type that represents both ends of the file.
-}
data Ends =
TOF -- ^Top of file
| EOF -- ^End of file
deriving (Eq, Ord, Show)
data Seek pos m a where
Seek :: pos -> Seek pos m ()
{- ^An effect that moves the cursor.
-}
makeSem ''Seek
{- |A wrapper type that represents an absolute position in the file.
-}
newtype Absolute a = Absolute a deriving (Eq, Ord, Show)
{- |A wrapper type that represents relative position from the current cursor position.
-}
newtype Relative a = Relative a deriving (Eq, Ord, Show)
{- |A wrapper type that represents relative position from the end of the file.
-}
newtype FromEnd a = FromEnd a deriving (Eq, Ord, Show)
data Read sz i m a where
Read :: sz -> Read sz i m i
{- ^An effect that gets file contents by the size 'sz' from the current
position.
-}
makeSem ''Read
{- |An effect that gets file contents from current position to the end of the
file.
-}
type ReadToEnd = Read ToEnd
{- |A singleton that represents the size from the current position to the end of
the file.
-}
data ToEnd = ToEnd deriving (Eq, Ord, Show)
-- |A singleton that represents the size 0.
data NullSize = NullSize deriving (Eq, Ord, Show)
{- |Transforms an 'Input' effect into an 'Read' effect with the fixed size.
-}
inputToRead :: Member (Read sz i) r => sz -> Sem (Input i ': r) a -> Sem r a
inputToRead sz = interpret \Input -> read sz
data Overwrite o m a where
Overwrite :: o -> Overwrite o m ()
{- ^An effect that overwrites file contents by the data 'o' from current
position.
-}
makeSem ''Overwrite
{- |Transforms an 'Output' effect into an `Overwrite` effect.
-}
outputToOverwrite :: Member (Overwrite o) r => Sem (Output o ': r) a -> Sem r a
outputToOverwrite = interpret \(Output o) -> overwrite o
data Extend o m a where
Extend :: o -> Extend o m ()
-- ^An effect that extends a file by the data 'o' from the end of a file.
-- The cursor is not moved.
makeSem ''Extend
data Append o m a where
Append :: o -> Append o m ()
-- ^An effect that extends a file by the data 'o' from the end of a file.
-- The cursor is moved to the end of the file after extending.
makeSem ''Append
{- |Transforms an 'Output' effect into an `Extend` effect.
-}
outputToExtend :: Member (Extend o) r => Sem (Output o ': r) a -> Sem r a
outputToExtend = interpret \(Output o) -> extend o
-- |Transforms an 'Output' effect into an `Append` effect.
outputToAppend :: Member (Append o) r => Sem (Output o ': r) a -> Sem r a
outputToAppend = interpret \(Output o) -> append o
data Resize sz m a where
Resize :: sz -> Resize sz m ()
{- ^An effect that resizes a file by the size 'sz'.
Note: The initial data in space made by a growing is interpreter-dependent.
-}
makeSem ''Resize