packages feed

liblawless 0.19.5 → 0.20.1

raw patch · 8 files changed

+287/−144 lines, 8 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- IO: AbsoluteSeek :: SeekMode
- IO: RelativeSeek :: SeekMode
- IO: SeekFromEnd :: SeekMode
- IO: binaryMode :: MonadIO m => Handle -> m ()
- IO: class MonadIO m => MonadManaged (m :: * -> *)
- IO: data Managed a :: * -> *
- IO: data SeekMode :: *
- IO: data TempFile
- IO: file :: AbsRel ar => File ar -> IOMode -> Managed Handle
- IO: hClose :: MonadIO m => Handle -> m ()
- IO: hIsEOF :: MonadIO m => Handle -> m Bool
- IO: hSeek :: Handle -> SeekMode -> Integer -> IO ()
- IO: managed :: (forall r. (a -> IO r) -> IO r) -> Managed a
- IO: runManaged :: Managed () -> IO ()
- IO: tempFile :: AbsDir -> RelFile -> Managed TempFile
- IO: textMode :: MonadIO m => Handle -> m ()
- IO: tfile :: AbsRel ar => File ar -> IOMode -> Managed Handle
- IO: using :: MonadManaged m => Managed a -> m a
- Text.Machine: readLines :: MonadIO m => Handle -> SourceT m Text
- Text.Machine: writeLines :: MonadIO m => Handle -> ProcessT m Text Text
+ IO: binaryFile :: (MonadIO m, MonadMask m, AbsRel ar) => File ar -> IOMode -> (Handle -> m a) -> m a
+ IO: binaryTemporaryFile :: (MonadIO m, MonadMask m, MonadThrow m) => AbsDir -> RelFile -> (TemporaryFile -> m a) -> m a
+ IO: class MonadThrow m => MonadCatch (m :: * -> *)
+ IO: class MonadCatch m => MonadMask (m :: * -> *)
+ IO: class Monad m => MonadThrow (m :: * -> *)
+ IO: close :: MonadIO m => Handle -> m ()
+ IO: data ParseError
+ IO: data TemporaryFile
+ IO: getLine :: (MonadIO m, MonadThrow m, Textual t) => m t
+ IO: hGetLine :: (MonadIO m, MonadThrow m, Textual t) => Handle -> m t
+ IO: hPutStr :: (MonadIO m, Printable p) => Handle -> p -> m ()
+ IO: hPutStrLn :: (MonadIO m, Printable p) => Handle -> p -> m ()
+ IO: instance Data.Textual.Printable IO.ParseError
+ IO: instance GHC.Classes.Eq IO.FileOffset
+ IO: instance GHC.Classes.Eq IO.FilePosition
+ IO: instance GHC.Classes.Eq IO.ParseError
+ IO: instance GHC.Classes.Ord IO.FileOffset
+ IO: instance GHC.Classes.Ord IO.FilePosition
+ IO: instance GHC.Classes.Ord IO.ParseError
+ IO: instance GHC.Enum.Enum IO.FileOffset
+ IO: instance GHC.Enum.Enum IO.FilePosition
+ IO: instance GHC.Exception.Exception IO.ParseError
+ IO: instance GHC.Num.Num IO.FileOffset
+ IO: instance GHC.Num.Num IO.FilePosition
+ IO: instance GHC.Real.Integral IO.FileOffset
+ IO: instance GHC.Real.Integral IO.FilePosition
+ IO: instance GHC.Real.Real IO.FileOffset
+ IO: instance GHC.Real.Real IO.FilePosition
+ IO: instance GHC.Show.Show IO.FileOffset
+ IO: instance GHC.Show.Show IO.FilePosition
+ IO: instance GHC.Show.Show IO.ParseError
+ IO: isEOF :: MonadIO m => Handle -> m Bool
+ IO: peReason :: Lens' ParseError Text
+ IO: peStack :: Lens' ParseError [Text]
+ IO: textFile :: (MonadIO m, MonadMask m, AbsRel ar) => File ar -> IOMode -> (Handle -> m a) -> m a
+ IO: textTemporaryFile :: (MonadIO m, MonadMask m, MonadThrow m) => AbsDir -> RelFile -> (TemporaryFile -> m a) -> m a
+ IO: withOffset :: (MonadIO m, MonadMask m) => Handle -> FileOffset -> (Handle -> m a) -> m a
+ IO: withPosition :: (MonadIO m, MonadMask m) => Handle -> FilePosition -> (Handle -> m a) -> m a
+ Text.IO: getLine :: (MonadIO m) => m Text
+ Text.IO: putStr :: (MonadIO m) => Text -> m ()
+ Text.IO: putStrLn :: (MonadIO m) => Text -> m ()
+ Text.IO: readLines :: forall (m :: * -> *). (MonadIO m) => Handle -> SourceT m Text
+ Text.IO: writeLines :: forall (m :: * -> *). (MonadIO m) => Handle -> ProcessT m Text Text
+ Time: data Seconds
+ Time: instance Data.Aeson.Types.Class.FromJSON Time.Seconds
+ Time: instance Data.Aeson.Types.Class.FromJSON Time.Time
+ Time: instance Data.Aeson.Types.Class.ToJSON Time.Seconds
+ Time: instance Data.Aeson.Types.Class.ToJSON Time.Time
+ Time: instance Data.Binary.Class.Binary Time.Seconds
+ Time: instance Data.Data.Data Time.Seconds
+ Time: instance Data.Textual.Textual Time.Time
+ Time: instance GHC.Classes.Eq Time.Seconds
+ Time: instance GHC.Classes.Ord Time.Seconds
+ Time: instance GHC.Enum.Enum Time.Seconds
+ Time: instance GHC.Num.Num Time.Seconds
+ Time: instance GHC.Real.Fractional Time.Seconds
+ Time: instance GHC.Real.Real Time.Seconds
+ Time: instance GHC.Real.RealFrac Time.Seconds
+ Time: instance GHC.Show.Show Time.Seconds
+ Time: seconds :: Iso' Double DiffTime
- IO: tfHandle :: Lens' TempFile Handle
+ IO: tfHandle :: Lens' TemporaryFile Handle
- IO: tfPath :: Lens' TempFile AbsFile
+ IO: tfPath :: Lens' TemporaryFile AbsFile
- Time: now :: IO Time
+ Time: now :: MonadIO m => m Time

Files

Source/IO.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TemplateHaskell, RecordWildCards #-} {-| Module:             IO Description:        General IO functions specialized for 'Printable' instances.@@ -10,113 +10,206 @@ -}  module IO (+    getLine,+    hGetLine,     putStr,     putStrLn,-    managed,-    Managed,-    MonadManaged(..),-    runManaged,-    TempFile,+    hPutStr,+    hPutStrLn,++    ParseError,+    peReason,+    peStack,++    MonadThrow,+    MonadCatch,+    MonadMask,++    Handle,++    TemporaryFile,     tfPath,     tfHandle,-    tempFile,++    binaryTemporaryFile,+    textTemporaryFile,++    withOffset,+    withPosition,+     MonadIO,     liftIO,-    PIO.hSeek,-    PIO.SeekMode(..),-    PIO.IOMode(..),-    file,-    tfile,-    textMode,-    binaryMode,-    hIsEOF,-    hClose,++    IOMode(..),+    binaryFile,+    textFile,++    isEOF,+    close,+     doesFileExist,     removeFile,-    PIO.Handle,-    SIO.stdin,-    SIO.stdout,-    SIO.stderr++    stdin,+    stdout,+    stderr     ) where  import Lawless import Control.Monad.IO.Class import qualified System.Path.Directory as D import qualified System.Path.IO as PIO-import qualified Data.Text.IO as T+import qualified Text.IO as TIO import Text import Textual import Path import qualified System.Path.PartClass as PC-import Control.Monad.Managed.Safe import Exception import qualified System.IO as SIO+import System.IO (Handle, stdin, stdout, stderr, SeekMode(..), IOMode(..))+import Data.Typeable +default (Text)+ -- * Printable I/O to stdio -liftPrintble ∷ (MonadIO m, Printable p) ⇒ (Text → IO ()) → p → m ()-liftPrintble f p = liftIO $ f (buildText ∘ print $ p)+data ParseError = ParseError {+    _peReason ∷ Text,+    _peStack ∷ [Text]+    } deriving (Eq, Ord, Typeable)+makeLenses ''ParseError +instance Printable ParseError where+    print (ParseError {..}) = fsep ": " [+        print "Parse error",+        print _peReason,+        parens $ fsep (print ", ") $ over traversed print _peStack+        ]++instance Show ParseError where+    show = buildString ∘ print++instance Exception ParseError++sTxt ∷ (MonadThrow m, Textual t) ⇒ Text → m t+sTxt t = case parseText t of+    Malformed s r → throwM $ ParseError (r ^. packed) $ over traversed (view packed) s+    Parsed v → return v++getLine ∷ (MonadIO m, MonadThrow m, Textual t) ⇒ m t+getLine = TIO.getLine ≫= sTxt++hGetLine ∷ (MonadIO m, MonadThrow m, Textual t) ⇒ Handle → m t+hGetLine h = TIO.hGetLine h ≫= sTxt++pTxt ∷ (Printable p)⇒ p → Text+pTxt = buildText ∘ print+ putStr ∷ (MonadIO m, Printable p) ⇒ p → m ()-putStr = liftPrintble T.putStr+putStr = TIO.putStr ∘ pTxt  putStrLn ∷ (MonadIO m, Printable p) ⇒ p → m ()-putStrLn = liftPrintble T.putStrLn+putStrLn = TIO.putStrLn ∘ pTxt +hPutStr ∷ (MonadIO m, Printable p) ⇒ Handle → p → m ()+hPutStr h = TIO.hPutStr h ∘ pTxt++hPutStrLn ∷ (MonadIO m, Printable p) ⇒ Handle → p → m ()+hPutStrLn h = TIO.hPutStrLn h ∘ pTxt++-- * Seek managers++newtype FileOffset = FileOffset Integer+    deriving (Eq, Ord, Show, Enum, Real, Num, Integral)+newtype FilePosition = FilePosition Integer+    deriving (Eq, Ord, Show, Enum, Real, Num, Integral)++seek ∷ (MonadIO m) ⇒ Handle → FileOffset → m ()+seek h o = liftIO $ SIO.hSeek h RelativeSeek (fromIntegral o)++seek_ ∷ (MonadIO m) ⇒ Handle → FilePosition → m ()+seek_ h p = liftIO $ SIO.hSeek h AbsoluteSeek (fromIntegral p)++tell ∷ (MonadIO m) ⇒ Handle → m FilePosition+tell h = liftIO $ fromIntegral <$> SIO.hTell h++withOffset ∷ (MonadIO m, MonadMask m) ⇒ Handle → FileOffset → (Handle → m a) → m a+withOffset h o f= do+    p ← tell h+    bracket_ (seek h o) (seek_ h p) (f h)++withPosition ∷ (MonadIO m, MonadMask m) ⇒ Handle → FilePosition → (Handle → m a) → m a+withPosition h p f = do+    o ← tell h+    bracket_ (seek_ h p) (seek_ h o) (f h)+ -- * Managed temporary files-data TempFile = TempFile {++data TemporaryFile = TemporaryFile {     _tfPath ∷ AbsFile,-    _tfHandle ∷ PIO.Handle+    _tfHandle ∷ Handle     }-makeLenses ''TempFile+makeLenses ''TemporaryFile -tempFile ∷ AbsDir → RelFile → Managed TempFile-tempFile pth tmpl =+temporaryFile ∷ (MonadIO m, MonadMask m) ⇒+    (Handle → m ()) → AbsDir → RelFile → (TemporaryFile → m a) → m a+temporaryFile m pth tmpl =     let-        open = do+        openT = do             (p, h) ← liftIO $ PIO.openTempFile pth tmpl-            liftIO $ binaryMode h-            return $ TempFile p h+            m h+            return $ TemporaryFile p h -        close tf = do+        closeT tf = do             liftIO $ PIO.hClose $ tf ^. tfHandle             liftIO $ D.removeFile $ tf ^. tfPath     in-        managed $ bracket open close+        bracket openT closeT --- * Managed files+binaryTemporaryFile ∷ (MonadIO m, MonadMask m, MonadThrow m) ⇒+    AbsDir → RelFile → (TemporaryFile → m a) → m a+binaryTemporaryFile = temporaryFile binaryMode --- | Binary files, no buffering.-file ∷ PC.AbsRel ar ⇒ File ar → PIO.IOMode → Managed PIO.Handle-file pth m = managed $ \fh → do-    liftIO $ PIO.withBinaryFile pth m $ \h → do-        binaryMode h-        fh h+textTemporaryFile ∷ (MonadIO m, MonadMask m, MonadThrow m) ⇒+    AbsDir → RelFile → (TemporaryFile → m a) → m a+textTemporaryFile = temporaryFile textMode --- | Text files, line-buffered.-tfile ∷ PC.AbsRel ar ⇒ File ar → PIO.IOMode → Managed PIO.Handle-tfile pth m =managed $ \fh → do-    liftIO $ PIO.withBinaryFile pth m $ \h → do-        textMode h-        fh h+-- * Managed files+open ∷ (MonadIO m, PC.AbsRel ar) ⇒ File ar → IOMode → (Handle → m ()) → m Handle+open p m t = do+    h ← liftIO $ PIO.openBinaryFile p m+    t h+    return h -textMode ∷ MonadIO m ⇒ PIO.Handle → m ()+textMode ∷ MonadIO m ⇒ Handle → m () textMode h = liftIO $     PIO.hSetBuffering h PIO.LineBuffering >>     PIO.hSetBinaryMode h False -binaryMode ∷ MonadIO m ⇒ PIO.Handle → m ()+binaryMode ∷ MonadIO m ⇒ Handle → m () binaryMode h = liftIO $     PIO.hSetBuffering h PIO.NoBuffering >>     PIO.hSetBinaryMode h True +-- | Binary files, no buffering.+binaryFile ∷ (MonadIO m, MonadMask m, PC.AbsRel ar) ⇒+    File ar → IOMode → (Handle → m a) → m a+binaryFile pth m =+    bracket (open pth m binaryMode) (close)++-- | Text files, line-buffered.+textFile ∷ (MonadIO m, MonadMask m, PC.AbsRel ar) ⇒+    File ar → IOMode → (Handle → m a) → m a+textFile pth m = do+    bracket (open pth m textMode) (close)+ -- * Lifted IO -hIsEOF ∷ MonadIO m ⇒ SIO.Handle → m Bool-hIsEOF = liftIO ∘ SIO.hIsEOF+isEOF ∷ MonadIO m ⇒ Handle → m Bool+isEOF = liftIO ∘ SIO.hIsEOF -hClose ∷ MonadIO m ⇒ SIO.Handle → m ()-hClose = liftIO ∘ SIO.hClose+close ∷ MonadIO m ⇒ Handle → m ()+close = liftIO ∘ SIO.hClose  doesFileExist ∷ (MonadIO m, PC.AbsRel ar) ⇒ File ar → m Bool doesFileExist = liftIO ∘ D.doesFileExist
Source/Text/IO.hs view
@@ -12,9 +12,14 @@     readFile,     writeFile,     appendFile,+    getLine,+    putStr,+    putStrLn,     hGetLine,     hPutStr,-    hPutStrLn+    hPutStrLn,+    readLines,+    writeLines     ) where  import Lawless@@ -23,7 +28,8 @@ import Data.Text (Text) import System.Path import Control.Monad.IO.Class-import System.Path.IO (Handle)+import System.Path.IO (Handle, hIsEOF)+import Machine  readFile ∷ (MonadIO m) ⇒ AbsRelFile → m Text readFile = liftIO ∘ TIO.readFile ∘ toString@@ -34,11 +40,31 @@ appendFile ∷ (MonadIO m) ⇒ AbsRelFile → Text → m () appendFile f t = liftIO $ TIO.appendFile (toString f) t +putStr ∷ (MonadIO m) ⇒ Text → m ()+putStr = liftIO ∘ TIO.putStr++putStrLn ∷ (MonadIO m) ⇒ Text → m ()+putStrLn = liftIO ∘ TIO.putStrLn+ hPutStr ∷ (MonadIO m) ⇒ Handle → Text → m () hPutStr h = liftIO ∘ TIO.hPutStr h  hPutStrLn ∷ (MonadIO m) ⇒ Handle → Text → m () hPutStrLn h = liftIO ∘ TIO.hPutStrLn h +getLine ∷ (MonadIO m) ⇒ m Text+getLine = liftIO TIO.getLine+ hGetLine ∷ (MonadIO m) ⇒ Handle → m Text hGetLine = liftIO ∘ TIO.hGetLine++-- * Machines++-- | Read lines of 'Text' from a 'Handle' until $EOF$ is reached.+readLines  ∷ ∀ (m ∷ * → *). (MonadIO m) ⇒ Handle → SourceT m Text+readLines h = repeatedly $ ifM (liftIO $ hIsEOF h) stop (hGetLine h)++-- | Write lines of 'Text' to a 'Handle' until there are no+-- more. Forwards them on.+writeLines ∷ ∀ (m ∷ * → *). (MonadIO m) ⇒ Handle → ProcessT m Text Text+writeLines h = repeatedly $ await ≫= \l → hPutStrLn h l ≫ return l
− Source/Text/Machine.hs
@@ -1,38 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}-{-|-Module:             Text.Machines-Description:        Machines for transducing Text streams.-Copyright:          © 2016 All rights reserved.-License:            GPL-3-Maintainer:         Evan Cofsky <>-Stability:          experimental-Portability:        POSIX--}--module Text.Machine (-    readLines,-    writeLines-    ) where--import Lawless-import IO-import Text-import Text.IO-import Machine---- | Read lines from a 'Handle' until $EOF$ is reached.-readLines ∷ MonadIO m ⇒ Handle → SourceT m Text-readLines h =-    let-        p = ifM (liftIO $ hIsEOF h) stop ((liftIO $ hGetLine h) >>= yield >> p)-    in-        construct p---- | Write lines to a 'Handle' until there are no more. Forwards them--- on.-writeLines ∷ MonadIO m ⇒ Handle → ProcessT m Text Text-writeLines h =-    let-        w = await >>= liftIO ∘ hPutStrLn h >> w-    in-        construct w
Source/Time.hs view
@@ -3,35 +3,71 @@ module Time   (     Time,+    Seconds,     ParseTime(..),     FormatTime(..),     _Time,     day,     time,-    now+    now,+    seconds   ) where -import Lawless-import Data.Time.Clock+import Data.Binary+import Data.Char+import Data.Data import Data.Time.Calendar+import Data.Time.Clock import Data.Time.Format import Generics-import Data.Binary-+import IO (MonadIO, liftIO)+import Lawless+import Text import qualified Textual as T+import qualified Parser as P+import Aeson +default (Text)+ newtype Time = Time UTCTime deriving (Show, Eq, Ord, ParseTime, FormatTime, Generic) makePrisms ''Time +deriving instance ToJSON Time+deriving instance FromJSON Time++timeFormat ∷ [Char]+timeFormat = (iso8601DateFormat (Just "%H:%M:%S.%q%z"))++-- | 'Lens' for the 'Day' component of a 'Time'. day :: Lens' Time Day day = lens (utctDay ∘ view _Time) (\(Time (UTCTime{..})) d → Time $ UTCTime d utctDayTime) +-- | 'Lens' for the 'DiffTime' component of a 'Time'. time ∷ Lens' Time DiffTime time = lens (utctDayTime ∘ view _Time) (\(Time (UTCTime{..})) t → Time $ UTCTime utctDay t) -now ∷ IO Time-now = Time <$> getCurrentTime+-- | Get the current system time.+now ∷ MonadIO m ⇒ m Time+now = liftIO $ Time <$> getCurrentTime +newtype Seconds = Seconds DiffTime+    deriving (Eq, Ord, Show, Enum, Fractional, Data, Num, Real, RealFrac)++-- | Convert between 'Double' and 'Seconds'.+seconds ∷ Iso' Double DiffTime+seconds = iso (fromRational ∘ toRational) (fromRational ∘ toRational)++instance FromJSON Seconds where+    parseJSON (Number n) = return $ Seconds (fromRational ∘ toRational $ n)+    parseJSON v = typeMismatch "Seconds" v++instance ToJSON Seconds where+    toJSON = Number ∘ fromRational ∘ toRational++instance Binary Seconds where+    put = put ∘ toRational+    get = Seconds ∘ fromRational <$> get+ instance Binary Time where   put t =     put (toModifiedJulianDay (t ^. day)) >>@@ -43,4 +79,21 @@     return ∘ Time $ UTCTime d t  instance T.Printable Time where-  print = T.print ∘ formatTime defaultTimeLocale (iso8601DateFormat (Just "%H:%M:%S%QZ"))+  print = T.print ∘formatTime defaultTimeLocale timeFormat++parseTimeFormats ∷ [[Char]]+parseTimeFormats = over traversed (iso8601DateFormat ∘ Just) [+    "%H:%M:%S%Q%z",+    "%H:%M:%S%QZ"+    ]++instance T.Textual Time where+    textual =+        let+            r = P.some+                (P.satisfy+                    (\c → isAlphaNum c ∨ anyOf traversed (c≡) (":+-." ∷ [Char]))+                )+            p f = (parseTimeM False defaultTimeLocale f)+        in+            P.choice $ over traversed (\f → P.try $ p f =≪ r) parseTimeFormats
+ Tests/Line.hs view
@@ -0,0 +1,35 @@+{-|+Module:             Line+Description:        Arbitrary Text Line.+Copyright:          © 2017 All rights reserved.+License:            GPL-3+Maintainer:         Evan Cofsky <evan@theunixman.com>+Stability:          experimental+Portability:        POSIX+-}++module Line (Line(..), readWriteLines) where++import Lawless hiding (mapping)+import Textual+import Arbitrary()+import Test.QuickCheck+import Text+import Text.IO+import IO hiding (putStrLn)+import Machine+import Path++newtype Line = Line Text deriving (Eq, Ord, Show)+instance Arbitrary Line where+    arbitrary = Line <$> suchThat arbitrary (allOf each (≥ ' '))+instance Printable Line where+    print (Line t) = print t++readWriteLines ∷+    (Traversable f, MonadMask m, MonadIO m) ⇒+    f Line → m [Line]+readWriteLines lns = textTemporaryFile (absDir "/tmp") (relFile "testTemp") $ \tf → do+    let h = tf ^. tfHandle+    runT_ $ supply lns (mapping $ \(Line t) → t) ⇝ writeLines h ⇝ autoM (\l → putStrLn l ≫ return l)+    runT $ readLines h ⇝ autoM (\l → putStrLn l ≫ return l) ⇝ mapping Line
Tests/TestTemporary.hs view
@@ -17,8 +17,7 @@ import Path import Text import Text.IO-import IO-import Control.Concurrent.STM+import IO hiding (hGetLine, hPutStrLn)  import Arbitrary() import Test.Framework@@ -26,24 +25,18 @@ import Test.Framework.Providers.QuickCheck2 (testProperty) import Test.QuickCheck import Test.QuickCheck.Monadic-default (Text)+import Line -newtype Line = Line Text deriving (Eq, Ord, Show)-instance Arbitrary Line where-    arbitrary = Line <$> suchThat arbitrary (not ∘ anyOf each (≡ '\n'))+default (Text)  prop_CheckBuffering ∷ Line → Property-prop_CheckBuffering (Line line) = monadicIO $ do+prop_CheckBuffering (Line l) = monadicIO $ do     m ← run $ do-        v ← atomically $ newEmptyTMVar-        runManaged $ do-            tf ← tempFile (absDir ("/tmp" ∷ Text)) (relFile ("testTemp" ∷ Text))+        binaryTemporaryFile (absDir "/tmp") (relFile "testTemp") $ \tf → do             let h = tf ^. tfHandle-            liftIO $ hPutStrLn h line-            liftIO $ hSeek h AbsoluteSeek 0-            liftIO $ hGetLine h >>= atomically ∘ putTMVar v-        liftIO $ atomically $ takeTMVar v-    assert (line ≡ m)+            withOffset h 0 $ \_ → hPutStrLn h l+            hGetLine h+    assert (l ≡ m)  properties ∷ Test properties = $(testGroupGenerator)
Tests/TestTextMachine.hs view
@@ -14,12 +14,7 @@ module TestTextMachine where  import Lawless-import Path import Text-import Text.Machine-import IO-import Control.Concurrent.STM-import Machine hiding (run)  import Arbitrary() import Test.Framework@@ -27,27 +22,14 @@ import Test.Framework.Providers.QuickCheck2 (testProperty) import Test.QuickCheck import Test.QuickCheck.Monadic-default (Text)--newtype Line = Line Text deriving (Eq, Ord, Show)-makePrisms ''Line+import Line -instance Arbitrary Line where-    arbitrary = Line <$> suchThat arbitrary (allOf each (≢ '\n'))+default (Text)  prop_CheckTextMachine ∷ [Line] → Property prop_CheckTextMachine lines = monadicIO $ do-    let tls = over traversed (view _Line) lines-    m ← run $ do-        v ← atomically $ newEmptyTMVar-        runManaged $ do-            tf ← tempFile (absDir ("/tmp" ∷ Text)) (relFile ("testTemp" ∷ Text))-            let h = tf ^. tfHandle-            runT_ $ supply tls $ writeLines h-            liftIO $ hSeek h AbsoluteSeek 0-            liftIO $ (runT $ readLines h) >>= atomically ∘ putTMVar v-        liftIO $ atomically $ takeTMVar v-    assert (tls == m)+    m ← run $ readWriteLines lines+    assert (lines == m)  properties ∷ Test properties = $(testGroupGenerator)
liblawless.cabal view
@@ -1,5 +1,5 @@ name:                liblawless-version:             0.19.5+version:             0.20.1 synopsis:            Prelude based on protolude for GHC 8 and beyond. license:             GPL-3 license-file:        LICENSE@@ -28,10 +28,10 @@ source-repository this   type:     git   location:   git@gitlab.com:misandrist/liblawless.git-  tag: v0.19.5+  tag: v0.20.1  library-  ghc-options: -Wall -Wno-redundant-constraints -O2+  ghc-options: -Wall -Wno-redundant-constraints -Wno-type-defaults -O2   exposed-modules:                   Aeson                   Arbitrary@@ -49,7 +49,6 @@                   Set                   Text                   Text.IO-                  Text.Machine                   Textual                   Time                   Tree