1
+ {-# OPTIONS_GHC -Wno-orphans #-}
2
+
1
3
module System.IO.NonInterleaved (
2
4
-- * Output functions
3
5
niPutStr
@@ -9,9 +11,13 @@ module System.IO.NonInterleaved (
9
11
, niTraceShowId
10
12
, niTraceM
11
13
, niTraceShowM
14
+ -- * Derived functionality
15
+ , niBracket
16
+ , niBracketLn
12
17
) where
13
18
14
19
import Control.Concurrent
20
+ import Control.Monad.Catch (ExitCase (.. ), generalBracket )
15
21
import System.IO
16
22
import System.IO.Temp (getCanonicalTemporaryDirectory )
17
23
import System.IO.Unsafe
@@ -73,6 +79,32 @@ niTraceM str = niTrace str $ pure ()
73
79
niTraceShowM :: (Applicative m , Show a ) => a -> m ()
74
80
niTraceShowM = niTraceM . show
75
81
82
+ {- ------------------------------------------------------------------------------
83
+ Derived functionality
84
+ -------------------------------------------------------------------------------}
85
+
86
+ -- | Print a message before and after an action
87
+ --
88
+ -- NOTE: We provide an (orphan) 'Functor' instance for 'ExitCase', which can
89
+ -- be useful in cases where @a@ is not showable.
90
+ niBracket ::
91
+ String -- ^ Message to print prior to the action
92
+ -> (ExitCase a -> String ) -- ^ Message to print after
93
+ -> IO a -> IO a
94
+ niBracket before after act = fmap (\ (a, () ) -> a) $
95
+ generalBracket
96
+ (niPutStr before)
97
+ (\ () -> niPutStr . after)
98
+ (\ () -> act)
99
+
100
+ -- | Like 'niBracket', but adding linebreaks.
101
+ --
102
+ -- 'niBracketLn' is to 'niBracket' as 'niPutStrLn' is to 'niPutStr'.
103
+ niBracketLn :: String -> (ExitCase a -> String ) -> IO a -> IO a
104
+ niBracketLn before after = niBracket (before ++ " \n " ) ((++ " \n " ) . after)
105
+
106
+ deriving stock instance Functor ExitCase
107
+
76
108
{- ------------------------------------------------------------------------------
77
109
Internal
78
110
-------------------------------------------------------------------------------}
0 commit comments