Skip to content

Commit

Permalink
Merge pull request #4 from well-typed/edsko/niBracket
Browse files Browse the repository at this point in the history
Add `niBracket`
  • Loading branch information
edsko authored Nov 9, 2024
2 parents f78acc4 + aa1aaae commit ab7dad0
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 1 deletion.
9 changes: 8 additions & 1 deletion niio.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,18 @@ common lang
ghc-options: -Wall
build-depends: base >= 4.14 && < 4.21

default-extensions:
DeriveFunctor
DerivingStrategies
StandaloneDeriving

library
import: lang
exposed-modules: System.IO.NonInterleaved
hs-source-dirs: src

build-depends:
temporary >= 1.3 && < 1.4
, exceptions >= 0.9 && < 0.11
, temporary >= 1.2.1 && < 1.4


32 changes: 32 additions & 0 deletions src/System/IO/NonInterleaved.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{-# OPTIONS_GHC -Wno-orphans #-}

module System.IO.NonInterleaved (
-- * Output functions
niPutStr
Expand All @@ -9,9 +11,13 @@ module System.IO.NonInterleaved (
, niTraceShowId
, niTraceM
, niTraceShowM
-- * Derived functionality
, niBracket
, niBracketLn
) where

import Control.Concurrent
import Control.Monad.Catch (ExitCase(..), generalBracket)
import System.IO
import System.IO.Temp (getCanonicalTemporaryDirectory)
import System.IO.Unsafe
Expand Down Expand Up @@ -73,6 +79,32 @@ niTraceM str = niTrace str $ pure ()
niTraceShowM :: (Applicative m, Show a) => a -> m ()
niTraceShowM = niTraceM . show

{-------------------------------------------------------------------------------
Derived functionality
-------------------------------------------------------------------------------}

-- | Print a message before and after an action
--
-- NOTE: We provide an (orphan) 'Functor' instance for 'ExitCase', which can
-- be useful in cases where @a@ is not showable.
niBracket ::
String -- ^ Message to print prior to the action
-> (ExitCase a -> String) -- ^ Message to print after
-> IO a -> IO a
niBracket before after act = fmap (\(a, ()) -> a) $
generalBracket
(niPutStr before)
(\() -> niPutStr . after)
(\() -> act)

-- | Like 'niBracket', but adding linebreaks.
--
-- 'niBracketLn' is to 'niBracket' as 'niPutStrLn' is to 'niPutStr'.
niBracketLn :: String -> (ExitCase a -> String) -> IO a -> IO a
niBracketLn before after = niBracket (before ++ "\n") ((++ "\n") . after)

deriving stock instance Functor ExitCase

{-------------------------------------------------------------------------------
Internal
-------------------------------------------------------------------------------}
Expand Down

0 comments on commit ab7dad0

Please sign in to comment.