packages feed

unbeliever 0.8.0.0 → 0.9.2.0

raw patch · 12 files changed

+449/−486 lines, 12 filesdep ~Cabaldep ~aesondep ~asyncPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: Cabal, aeson, async, bytestring, chronologique, containers, deepseq, directory, exceptions, fingertree, gauge, hashable, hourglass, hspec, mtl, prettyprinter, prettyprinter-ansi-terminal, safe-exceptions, scientific, stm, template-haskell, terminal-size, text, text-short, transformers, unix, unordered-containers, vector

API changes (from Hackage documentation)

- Core.Data.Structures: instance Core.Data.Structures.Key ε => Core.Data.Structures.Collection (Data.HashSet.HashSet ε)
- Core.Text.Rope: append :: Textual α => α -> Rope -> Rope
- Core.Text.Rope: contains :: Char -> Rope -> Bool
- Core.Text.Rope: insert :: Int -> Rope -> Rope -> Rope
- Core.Text.Rope: split :: Int -> Rope -> (Rope, Rope)
- Core.Text.Rope: width :: Rope -> Int
- Core.Text.Utilities: instance Core.Text.Utilities.Render [GHC.Types.Char]
+ Core.Data.Structures: instance Core.Data.Structures.Key ε => Core.Data.Structures.Collection (Data.HashSet.Base.HashSet ε)
+ Core.System.Base: data SomeException
+ Core.System.Base: finally :: MonadMask m => m a -> m b -> m a
+ Core.System.Base: impureThrow :: Exception e => e -> a
+ Core.Text.Bytes: instance Core.Text.Bytes.Binary Core.Text.Bytes.Bytes
+ Core.Text.Rope: appendRope :: Textual α => α -> Rope -> Rope
+ Core.Text.Rope: containsCharacter :: Char -> Rope -> Bool
+ Core.Text.Rope: emptyRope :: Rope
+ Core.Text.Rope: insertRope :: Int -> Rope -> Rope -> Rope
+ Core.Text.Rope: splitRope :: Int -> Rope -> (Rope, Rope)
+ Core.Text.Rope: widthRope :: Rope -> Int
+ Core.Text.Utilities: breakLines :: Rope -> [Rope]
+ Core.Text.Utilities: breakPieces :: (Char -> Bool) -> Rope -> [Rope]
+ Core.Text.Utilities: breakWords :: Rope -> [Rope]
+ Core.Text.Utilities: instance Core.Text.Utilities.Render GHC.Types.Char
+ Core.Text.Utilities: instance Core.Text.Utilities.Render a => Core.Text.Utilities.Render [a]
- Core.Program.Execute: terminate :: Int -> Program τ ()
+ Core.Program.Execute: terminate :: Int -> Program τ α

Files

LICENCE view
@@ -1,6 +1,6 @@ Opinionated Haskell Interoperability -Copyright © 2018 Operational Dynamics Consulting, Pty Ltd and Others+Copyright © 2018-2019 Operational Dynamics Consulting, Pty Ltd and Others All rights reserved.  Redistribution and use in source and binary forms, with or without
lib/Core/Program/Execute.hs view
@@ -1,9 +1,6 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE StrictData #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE DeriveFunctor #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE BangPatterns #-}@@ -272,7 +269,7 @@ -- putting to the quit MVar initiates the cleanup and exit sequence, -- but throwing the exception also aborts execution and starts unwinding -- back up the stack.-terminate :: Int -> Program τ ()+terminate :: Int -> Program τ α terminate code =   let     exit = case code of
lib/Core/Program/Logging.hs view
@@ -160,7 +160,7 @@      let display = case potentialValue of             Just value ->-                if contains '\n' value+                if containsCharacter '\n' value                     then text <> " =\n" <> value                     else text <> " = " <> value             Nothing -> text
lib/Core/System/Base.hs view
@@ -21,12 +21,16 @@       {-** from Control.Exception.Safe -}       {-| Re-exported from "Control.Exception.Safe" in the __safe-exceptions__ package: -}     , Exception(..)+    , SomeException     , throw+    , impureThrow     , bracket     , catch+    , finally     ) where -import Control.Exception.Safe (Exception(..), throw, bracket, catch)+import Control.Exception.Safe (Exception(..), SomeException, throw+    , bracket, catch, finally, impureThrow) import Control.Monad.IO.Class (MonadIO, liftIO) import System.IO (Handle, stdin, stdout, stderr, hFlush) import System.IO.Unsafe (unsafePerformIO)
lib/Core/Text/Bytes.hs view
@@ -74,6 +74,10 @@     fromBytes :: Bytes -> α     intoBytes :: α -> Bytes +instance Binary Bytes where+    fromBytes = id+    intoBytes = id+ {-| from "Data.ByteString" Strict -} instance Binary B.ByteString where     fromBytes (StrictBytes b') = b'
lib/Core/Text/Rope.hs view
@@ -74,12 +74,13 @@ module Core.Text.Rope     ( {-* Rope type -}       Rope-    , width-    , split-    , insert-    , contains+    , emptyRope+    , widthRope+    , splitRope+    , insertRope+    , containsCharacter       {-* Interoperation and Output -}-    , Textual(fromRope, intoRope, append)+    , Textual(fromRope, intoRope, appendRope)     , hWrite       {-* Internals -}     , unRope@@ -93,10 +94,11 @@     , hPutBuilder) import qualified Data.ByteString.Lazy as L (ByteString, toStrict     , foldrChunks)-import Data.String (IsString(..)) import qualified Data.FingerTree as F (FingerTree, Measured(..), empty-    , singleton, (><), (<|), (|>), search, SearchResult(..))+    , singleton, (><), (<|), (|>), search, SearchResult(..), null) import Data.Foldable (foldr, foldr', foldMap, toList, any)+import Data.Hashable (Hashable, hashWithSalt)+import Data.String (IsString(..)) import qualified Data.Text as T (Text) import qualified Data.Text.Lazy as U (Text, fromChunks, foldrChunks     , toStrict)@@ -107,7 +109,6 @@     , fromText, toText, fromByteString, pack, unpack     , append, empty, toBuilder, splitAt) import qualified Data.Text.Short.Unsafe as S (fromByteStringUnsafe)-import Data.Hashable (Hashable, hashWithSalt) import GHC.Generics (Generic) import System.IO (Handle) @@ -141,8 +142,8 @@  This involves considerable appending of data, very very occaisionally inserting it. Often the pieces are tiny. To add text to a @Rope@ use the-'append' method as below or ('Data.Semigroup.<>') from "Data.Monoid" (like you-would have with a @Builder@).+'appendRope' method as below or the ('Data.Semigroup.<>') operator from+"Data.Monoid" (like you would have with a @Builder@).  Output to a @Handle@ can be done efficiently with 'hWrite'. -}@@ -203,20 +204,35 @@ -- FingerTree Strand or Builder (Strand)  instance IsString Rope where-    fromString = Rope . F.singleton . S.pack+    fromString "" = emptyRope+    fromString xs = Rope . F.singleton . S.pack $ xs  instance Semigroup Rope where-    (<>) (Rope x1) (Rope x2) = Rope ((F.><) x1 x2) -- god I hate these operators+    (<>) text1@(Rope x1) text2@(Rope x2) =+        if F.null x2+            then text1+            else if F.null x1+                then text2+                else Rope ((F.><) x1 x2) -- god I hate these operators  instance Monoid Rope where-    mempty = Rope F.empty+    mempty = emptyRope     mappend = (<>)  {-|+An zero-length 'Rope'. You can also use @\"\"@ presuming the+__@OverloadedStrings@__ language extension is turned on in your source+file.+-}+emptyRope :: Rope+emptyRope = Rope F.empty+{-# INLINABLE emptyRope #-}++{-| Get the length of this text, in characters. -}-width :: Rope -> Int-width = foldr' f 0 . unRope+widthRope :: Rope -> Int+widthRope = foldr' f 0 . unRope   where     f piece count = S.length piece + count @@ -226,25 +242,25 @@ Examples:  @-λ> __split 0 \"abcdef\"__+λ> __splitRope 0 \"abcdef\"__ (\"\", \"abcdef\")-λ> __split 3 \"abcdef\"__+λ> __splitRope 3 \"abcdef\"__ (\"abc\", \"def\")-λ> __split 6 \"abcdef\"__+λ> __splitRope 6 \"abcdef\"__ (\"abcdef\",\"\") @  Going off either end behaves sensibly:  @-λ> __split 7 \"abcdef\"__+λ> __splitRope 7 \"abcdef\"__ (\"abcdef\",\"\")-λ> __split (-1) \"abcdef\"__+λ> __splitRope (-1) \"abcdef\"__ (\"\", \"abcdef\") @ -}-split :: Int -> Rope -> (Rope,Rope)-split i text@(Rope x) =+splitRope :: Int -> Rope -> (Rope,Rope)+splitRope i text@(Rope x) =   let     pos = Width i     result = F.search (\w1 _ -> w1 >= pos) x@@ -266,21 +282,20 @@ Examples:  @-λ> __insert 3 \"Con\" \"Def 1\"__+λ> __insertRope 3 \"Con\" \"Def 1\"__ "DefCon 1"-λ> __insert 0 \"United \" \"Nations\"__+λ> __insertRope 0 \"United \" \"Nations\"__ "United Nations" @ -}-insert :: Int -> Rope -> Rope -> Rope-insert 0 (Rope new) (Rope x) = Rope ((F.><) new x)-insert i (Rope new) text =+insertRope :: Int -> Rope -> Rope -> Rope+insertRope 0 (Rope new) (Rope x) = Rope ((F.><) new x)+insertRope i (Rope new) text =   let-    (Rope before,Rope after) = split i text+    (Rope before,Rope after) = splitRope i text   in     Rope (mconcat [before, new, after]) - -- -- Manual instance to get around the fact that FingerTree doesn't have a -- Hashable instance. If this were ever to become a hotspot we could@@ -311,11 +326,11 @@ collector manage the memory, so instances are expected to /copy/ these substrings out of pinned memory. -The @ByteString@ instance requires that its content be valid UTF-8. If not an-empty @Rope@ will be returned.+The @ByteString@ instance requires that its content be valid UTF-8. If not+an empty @Rope@ will be returned.  Several of the 'fromRope' implementations are expensive and involve a lot-of intermiate allocation and copying. If you're ultimately writing to a+of intermediate allocation and copying. If you're ultimately writing to a handle prefer 'hWrite' which will write directly to the output buffer. -} class Textual α where@@ -333,8 +348,8 @@ text (which will work just fine, but for some types more efficient implementations are possible).     -}-    append :: α -> Rope -> Rope-    append thing text = text <> intoRope thing+    appendRope :: α -> Rope -> Rope+    appendRope thing text = text <> intoRope thing  instance Textual (F.FingerTree Width S.ShortText) where     fromRope = unRope@@ -343,13 +358,13 @@ instance Textual Rope where     fromRope = id     intoRope = id-    append (Rope x2) (Rope x1) = Rope ((F.><) x1 x2)+    appendRope (Rope x2) (Rope x1) = Rope ((F.><) x1 x2)  {-| from "Data.Text.Short" -} instance Textual S.ShortText where     fromRope = foldr S.append S.empty . unRope     intoRope = Rope . F.singleton-    append piece (Rope x) = Rope ((F.|>) x piece)+    appendRope piece (Rope x) = Rope ((F.|>) x piece)  {-| from "Data.Text" Strict -} instance Textual T.Text where@@ -359,7 +374,7 @@         f piece built = (<>) (U.fromText (S.toText piece)) built      intoRope t = Rope (F.singleton (S.fromText t))-    append chunk (Rope x) = Rope ((F.|>) x (S.fromText chunk))+    appendRope chunk (Rope x) = Rope ((F.|>) x (S.fromText chunk))  {-| from "Data.Text.Lazy" -} instance Textual U.Text where@@ -379,7 +394,7 @@         Nothing -> Rope F.empty         -- bad      -- ditto-    append b' (Rope x) = case S.fromByteString b' of+    appendRope b' (Rope x) = case S.fromByteString b' of         Just piece -> Rope ((F.|>) x piece)         Nothing -> (Rope x)             -- bad @@ -449,12 +464,12 @@ example:  @-    if 'contains' '\n' text+    if 'containsCharacter' \'\n\' text         then handleComplexCase         else keepItSimple @ -}-contains :: Char -> Rope -> Bool-contains q (Rope x) = any j x+containsCharacter :: Char -> Rope -> Bool+containsCharacter q (Rope x) = any j x   where     j piece = S.any (\c -> c == q) piece
lib/Core/Text/Utilities.hs view
@@ -16,18 +16,22 @@     , render       {-* Helpers -}     , indefinite+    , breakWords+    , breakLines+    , breakPieces     , wrap     , underline       {-* Multi-line strings -}     , quote ) where -import qualified Data.FingerTree as F ((<|), ViewL(..), viewl)+import Data.Char (isSpace)+import qualified Data.FingerTree as F ((<|), ViewL(..), viewl, singleton) import qualified Data.List as List (foldl', dropWhileEnd) import Data.Monoid ((<>)) import qualified Data.Text as T-import qualified Data.Text.Lazy.Builder as T-import qualified Data.Text.Short as S (ShortText, uncons, toText)+import qualified Data.Text.Short as S (ShortText, uncons, toText, empty+    , null, breakEnd, append, dropEnd) import Data.Text.Prettyprint.Doc (Doc, layoutPretty , reAnnotateS     , pretty, emptyDoc     , LayoutOptions(LayoutOptions)@@ -73,11 +77,16 @@         f :: S.ShortText -> Doc () -> Doc ()         f piece built = (<>) (pretty (S.toText piece)) built -instance Render [Char] where-    type Token [Char] = ()+instance Render Char where+    type Token Char = ()     colourize = const mempty-    intoDocA cs = pretty cs+    intoDocA c = pretty c +instance (Render a) => Render [a] where+    type Token [a] = Token a+    colourize = const mempty+    intoDocA = mconcat . fmap intoDocA+ instance Render T.Text where     type Token T.Text = ()     colourize = const mempty@@ -134,33 +143,143 @@                 else intoRope ("a " F.<| x)  {-|+Split a passage of text into a list of words. A line is broken wherever+there is one or more whitespace characters, as defined by "Data.Char"'s+'Data.Char.isSpace'.++Examples:++@+λ> __breakWords \"This is a test\"__+[\"This\",\"is\",\"a\",\"test\"]+λ> __breakWords (\"St\" <> \"op and \" <> \"go left\")__+[\"Stop\",\"and\",\"go\",\"left\"]+λ> __breakWords emptyRope__+[]+@+-}+breakWords :: Rope -> [Rope]+breakWords text = breakPieces isSpace text++{-|+Split a paragraph of text into a list of its individual lines. The+paragraph will be broken wherever there is a @'\n'@ character.+-}+breakLines :: Rope -> [Rope]+breakLines text = breakPieces isNewline text++isNewline :: Char -> Bool+isNewline c = c == '\n'++{-|+Break a Rope into pieces whereever the given predicate function returns+@True@. If found, that character will not be included on either side.+-}+breakPieces :: (Char -> Bool) -> Rope -> [Rope]+breakPieces predicate text =+  let+    (final,list) = foldr (finder predicate) (S.empty,[]) (unRope text)+    l = intoRope (F.singleton final)+  in+    if S.null final+        then list+        else l:list++finder+    :: (Char -> Bool)+    -> S.ShortText+    -> (S.ShortText,[Rope])+    -> (S.ShortText,[Rope])+finder predicate piece (accum,list) =+  let+    done = S.null piece++    -- λ> S.breakEnd isSpace "a d"+    -- ("a","d")+    --+    -- λ> S.breakEnd isSpace " and"+    -- (" ","and")+    --+    -- λ> S.breakEnd isSpace "and "+    -- ("and ","")+    --+    -- λ> S.breakEnd isSpace ""+    -- ("","")+    --+    -- λ> S.breakEnd isSpace " "+    -- (" ","")++    (remainder,fragment) = S.breakEnd predicate piece++    -- Are we in the middle of a word? We are if the carry forward is+    -- non-zero length.+    --+    -- Did we find a word in the current piece? If so, then if we are in+    -- the middle of accumulating a word, we add the new piece to it.++    found  = not (S.null fragment)+    middle = not (S.null accum)++    accum' = if found+                then if middle+                    then S.append fragment accum+                    else fragment+                else accum++    -- Did we find a space? We did if remainder is non-zero length.+    -- Finding a space means flushing out the accumulator (though only if+    -- there's actually something there). We have to drop that whitespace+    -- before iterating.++    space = not (S.null remainder)+    empty = S.null accum'+    word = intoRope accum'++    list' = if empty+                then list+                else word:list++    remainder' = S.dropEnd 1 remainder+  in+    if done+        then (accum',list)+        else if space+            then finder predicate remainder' (S.empty,list')+            else finder predicate remainder (accum',list)++{-| Often the input text represents a paragraph, but does not have any internal newlines (representing word wrapping). This function takes a line of text-and inserts newlines to simulate such folding. It also appends a trailing-newline to finish the paragraph.+and inserts newlines to simulate such folding, keeping the line under+the supplied maximum width.++A single word that is excessively long will be included as-is on its own+line (that line will exceed the desired maxium width).++Any trailing newlines will be removed. -} wrap :: Int -> Rope -> Rope wrap margin text =   let-    built = wrapHelper margin (T.words (fromRope text))+    built = wrapHelper margin (breakWords text)   in-    intoRope (T.toLazyText built)+    built -wrapHelper :: Int -> [T.Text] -> T.Builder+wrapHelper :: Int -> [Rope] -> Rope wrapHelper _ [] = ""-wrapHelper _ [x]  = T.fromText x+wrapHelper _ [x]  = x wrapHelper margin (x:xs) =-    snd $ List.foldl' (wrapLine margin) (T.length x, T.fromText x) xs+    snd $ List.foldl' (wrapLine margin) (widthRope x, x) xs -wrapLine :: Int -> (Int, T.Builder) -> T.Text -> (Int, T.Builder)+wrapLine :: Int -> (Int, Rope) -> Rope -> (Int, Rope) wrapLine margin (pos,builder) word =   let-    wide = T.length word+    wide = widthRope word     wide' = pos + wide + 1   in     if wide' > margin-        then (wide , builder <> "\n" <> T.fromText word)-        else (wide', builder <> " "  <> T.fromText word)+        then (wide , builder <> "\n" <> word)+        else (wide', builder <> " "  <> word)   underline :: Char -> Rope -> Rope
tests/CheckRopeBehaviour.hs view
@@ -30,9 +30,9 @@             unRope ("Hello" :: Rope) `shouldBe` F.singleton (S.pack "Hello")          it "calculates length accurately" $ do-            width hydrogen `shouldBe` 2-            width sulfate `shouldBe` 3-            width (hydrogen <> sulfate) `shouldBe` 5+            widthRope hydrogen `shouldBe` 2+            widthRope sulfate `shouldBe` 3+            widthRope (hydrogen <> sulfate) `shouldBe` 5          it "Eq instance behaves" $ do              ("" :: Rope) == ("" :: Rope) `shouldBe` True@@ -48,7 +48,7 @@              ("H₂" :: Rope) <> ("SO₄" :: Rope)  `shouldBe` ("H₂SO₄" :: Rope)          it "concatonates two Ropes correctly (Textual)" $ do-             append ("SO₄" :: Rope) ("H₂" :: Rope) `shouldBe` ("H₂SO₄" :: Rope)+             appendRope ("SO₄" :: Rope) ("H₂" :: Rope) `shouldBe` ("H₂SO₄" :: Rope)          it "exports to ByteString" $           let@@ -68,32 +68,32 @@             List.splitAt 3 ("123456789" :: String) `shouldBe` ("123", "456789")              -- expect same behaviour of Rope-            split 0 ("123456789" :: Rope) `shouldBe` ("", "123456789")-            split 3 ("123456789" :: Rope) `shouldBe` ("123", "456789")-            split 9 ("123456789" :: Rope) `shouldBe` ("123456789","")-            split 10 ("123456789" :: Rope) `shouldBe` ("123456789","")-            split (-1) ("123456789" :: Rope) `shouldBe` ("", "123456789")+            splitRope 0 ("123456789" :: Rope) `shouldBe` ("", "123456789")+            splitRope 3 ("123456789" :: Rope) `shouldBe` ("123", "456789")+            splitRope 9 ("123456789" :: Rope) `shouldBe` ("123456789","")+            splitRope 10 ("123456789" :: Rope) `shouldBe` ("123456789","")+            splitRope (-1) ("123456789" :: Rope) `shouldBe` ("", "123456789") -            -- exercise splitting at and between piece boundaries-            split 0 compound `shouldBe` ("", "3-ethyl-4-methylhexane")-            split 1 compound `shouldBe` ("3", "-ethyl-4-methylhexane")-            split 2 compound `shouldBe` ("3-", "ethyl-4-methylhexane")-            split 4 compound `shouldBe` ("3-et", "hyl-4-methylhexane")+            -- exercise splitRopeting at and between piece boundaries+            splitRope 0 compound `shouldBe` ("", "3-ethyl-4-methylhexane")+            splitRope 1 compound `shouldBe` ("3", "-ethyl-4-methylhexane")+            splitRope 2 compound `shouldBe` ("3-", "ethyl-4-methylhexane")+            splitRope 4 compound `shouldBe` ("3-et", "hyl-4-methylhexane")             --                             1234567890-            split 10 compound `shouldBe` ("3-ethyl-4-", "methylhexane")-            split 11 compound `shouldBe` ("3-ethyl-4-m", "ethylhexane")-            split 16 compound `shouldBe` ("3-ethyl-4-methyl", "hexane")-            split 21 compound `shouldBe` ("3-ethyl-4-methylhexan", "e")-            width compound `shouldBe` 22-            split 22 compound `shouldBe` ("3-ethyl-4-methylhexane", "")-            split 23 compound `shouldBe` ("3-ethyl-4-methylhexane", "")-            split (-1) compound `shouldBe` ("", "3-ethyl-4-methylhexane")+            splitRope 10 compound `shouldBe` ("3-ethyl-4-", "methylhexane")+            splitRope 11 compound `shouldBe` ("3-ethyl-4-m", "ethylhexane")+            splitRope 16 compound `shouldBe` ("3-ethyl-4-methyl", "hexane")+            splitRope 21 compound `shouldBe` ("3-ethyl-4-methylhexan", "e")+            widthRope compound `shouldBe` 22+            splitRope 22 compound `shouldBe` ("3-ethyl-4-methylhexane", "")+            splitRope 23 compound `shouldBe` ("3-ethyl-4-methylhexane", "")+            splitRope (-1) compound `shouldBe` ("", "3-ethyl-4-methylhexane")          it "does insertion correctly" $ do-            insert 3 "two" "onethree" `shouldBe` "onetwothree"-            insert 3 "Con" "Def 1" `shouldBe` "DefCon 1"-            insert 0 "one" "twothree" `shouldBe` "onetwothree"-            insert 6 "three" "onetwo" `shouldBe` "onetwothree"+            insertRope 3 "two" "onethree" `shouldBe` "onetwothree"+            insertRope 3 "Con" "Def 1" `shouldBe` "DefCon 1"+            insertRope 0 "one" "twothree" `shouldBe` "onetwothree"+            insertRope 6 "three" "onetwo" `shouldBe` "onetwothree"      describe "QuasiQuoted string literals" $       do@@ -110,3 +110,64 @@ World             |] `shouldBe` ("Hello\nWorld\n" :: Rope) +    describe "Splitting into words" $ do+        it "single piece containing multiple words splits correctly" $+          let+            text = "This is a test"+          in do+            breakWords text `shouldBe` ["This","is","a","test"]++        it "single piece, long run of whitespace splits correctly" $+          let+            text = "This is\na    test"+          in do+            breakWords text `shouldBe` ["This","is","a","test"]++        it "text spanning two pieces can be split into words" $+          let+            text = "This is " <> "a test"+          in do+            breakWords text `shouldBe` ["This","is","a","test"]++        it "text spanning many pieces can be split into words" $+          let+            text = "st" <> "" <> "op" <> "" <> " " <> " " <> "and go" <> "op"+          in do+            breakWords text `shouldBe` ["stop","and","goop"]++        it "empty and whitespace-only corner cases handled correctly " $+          let+            text = "  " <> "" <> "stop" <> "" <> "  "+          in do+            breakWords text `shouldBe` ["stop"]++    describe "Splitting into lines" $ do+        it "single piece containing multiple lines splits correctly" $+          let+            para = [quote|+This is a test+of the Emergency+Broadcast+System, beeeeep+|]+          in do+            breakLines para `shouldBe`+                [ "This is a test"+                , "of the Emergency"+                , "Broadcast"+                , "System, beeeeep"+                ]++    describe "Formatting paragraphs" $ do+        it "multi-line paragraph rewraps correctly" $+          let+            para = [quote|+Hello this is+a test+ of the Emergency Broadcast System+            |]+          in+            wrap 20 para `shouldBe` [quote|+Hello this is a test+of the Emergency+Broadcast System|]
− tests/SimpleExperiment.hs
@@ -1,111 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE OverloadedLists #-}-{-# LANGUAGE QuasiQuotes #-}-{-# LANGUAGE TemplateHaskell #-}-{-# OPTIONS_GHC -fno-warn-unused-imports #-}-{-# OPTIONS_GHC -fno-warn-unused-top-binds #-}-{-# OPTIONS_GHC -fno-warn-missing-signatures #-}-{-# OPTIONS_GHC -fno-warn-name-shadowing #-}-{-# OPTIONS_GHC -fno-warn-unused-do-bind #-}----import Data.Text (Text)-import Control.Concurrent (threadDelay)-import Control.Monad (replicateM_)-import qualified Data.ByteString.Char8 as S-import qualified Data.HashMap.Strict as HashMap-import Data.Text.Prettyprint.Doc (layoutPretty, defaultLayoutOptions, Pretty(..))-import Data.Text.Prettyprint.Doc.Render.Text (renderStrict)--import Core.Data-import Core.Text-import Core.Encoding-import Core.Program-import Core.System--k = JsonKey "intro"-v = JsonString "Hello"--j = JsonObject-        [ (k, v)-        , (JsonKey "song", JsonString "Thriller")-        , ("other", "A very long name for the \"shadow of the moon\".")-        , (JsonKey "four", JsonObject-                [ (JsonKey "n1", r)-                ])-        ]--b = intoBytes (S.pack "{\"cost\": 4500}")--r = JsonArray [JsonBool False, JsonNull, 42]--data Boom = Boom-    deriving Show--instance Exception Boom--program :: Program None ()-program = do-    event "Starting..."--    params <- getCommandLine-    debugS "params" params--    level <- getVerbosityLevel-    debugS "level" level--    name <- getProgramName-    debug "programName" name--    setProgramName "hello"--    name <- getProgramName-    debug "programName" name--    debugR "key" k-    event "Verify internal values"--    state <- getApplicationState-    debugS "state" state--    let x = encodeToUTF8 j-    writeS x--    let (Just y) = decodeFromUTF8 b-    writeS y-    writeS (encodeToUTF8 y)-    writeR (encodeToUTF8 y)-    writeS (encodeToUTF8 r)--    debugR "packet" j--    event "Clock..."--    fork $ do-        sleep 1.5-        event "Wakey wakey"-        throw Boom--    replicateM_ 5 $ do-        sleep 0.5-        event "tick"---    event "Brr! It's cold"-    terminate 0--version :: Version-version = $(fromPackage)--main :: IO ()-main = do-    context <- configure version None (simple-        [ Option "quiet" (Just 'q') Empty [quote|-            Supress normal output.-          |]-        , Argument "filename" [quote|-            The file you want to frobnicate.-          |]-        , Variable "HOME" "Home directory"-        ])--    executeWith context program
− tests/Snippet.hs
@@ -1,31 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE QuasiQuotes #-}-{-# OPTIONS_GHC -fno-warn-unused-imports #-}-{-# OPTIONS_GHC -fno-warn-unused-top-binds #-}-{-# OPTIONS_GHC -fno-warn-missing-signatures #-}-{-# OPTIONS_GHC -fno-warn-unused-do-bind #-}--import qualified Data.ByteString.Char8 as C--import Core.Program-import Core.Text-import Core.System--b = intoBytes (C.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")--data Boom = Boom deriving Show-instance Exception Boom--main :: IO ()-main = execute $ do-    event "Processing..."-    debugR "b" b--    let x = error "No!"--    write $ case x of-        Nothing -> "Nothing!"--    sleep 0.2--    write "Done"
tests/TestSuite.hs view
@@ -2,6 +2,7 @@  import Test.Hspec +import Core.System import CheckRopeBehaviour import CheckBytesBehaviour import CheckContainerBehaviour@@ -11,8 +12,7 @@  main :: IO () main = do-    hspec suite-    putStrLn "."+    finally (hspec suite) (putStrLn ".")  suite :: Spec suite = do
unbeliever.cabal view
@@ -1,260 +1,165 @@ cabal-version: 1.12---- This file has been generated from package.yaml by hpack version 0.31.1.------ see: https://github.com/sol/hpack------ hash: dc4af83e0e28d0d48d8e6550b7def407de3c5e3cc34d5c6380ecbfdc74229985--name:           unbeliever-version:        0.8.0.0-synopsis:       Opinionated Haskell Interoperability-description:    A library to help build command-line programs, both tools and-                longer-running daemons.-                .-                A description of this package, a list of features, and some background-                to its design is contained in the-                <https://github.com/oprdyn/unbeliever/blob/master/README.markdown README>-                on GitHub.-                .-                Useful starting points in the documentation are "Core.Program.Execute"-                and "Core.Text.Rope".-category:       System-stability:      experimental-homepage:       https://github.com/oprdyn/unbeliever#readme-bug-reports:    https://github.com/oprdyn/unbeliever/issues-author:         Andrew Cowie <andrew@operationaldynamics.com>-maintainer:     Andrew Cowie <andrew@operationaldynamics.com>-copyright:      © 2018 Operational Dynamics Consulting Pty Ltd, and Others-license:        BSD3-license-file:   LICENCE-tested-with:    GHC == 8.4-build-type:     Simple+name: unbeliever+version: 0.9.2.0+license: BSD3+license-file: LICENCE+copyright: © 2018-2019 Operational Dynamics Consulting Pty Ltd, and Others+maintainer: Andrew Cowie <andrew@operationaldynamics.com>+author: Andrew Cowie <andrew@operationaldynamics.com>+stability: experimental+tested-with: ghc ==8.6.4+homepage: https://github.com/oprdyn/unbeliever#readme+bug-reports: https://github.com/oprdyn/unbeliever/issues+synopsis: Opinionated Haskell Interoperability+description:+    A library to help build command-line programs, both tools and+    longer-running daemons.+    .+    A description of this package, a list of features, and some background+    to its design is contained in the+    <https://github.com/oprdyn/unbeliever/blob/master/README.markdown README>+    on GitHub.+    .+    Useful starting points in the documentation are "Core.Program.Execute"+    and "Core.Text.Rope".+category: System+build-type: Simple  source-repository head-  type: git-  location: https://github.com/oprdyn/unbeliever--flag development-  manual: True-  default: False+    type: git+    location: https://github.com/oprdyn/unbeliever  library-  exposed-modules:-      Core.Data-      Core.Data.Structures-      Core.Encoding-      Core.Encoding.Json-      Core.Program-      Core.Program.Arguments-      Core.Program.Execute-      Core.Program.Logging-      Core.Program.Metadata-      Core.Program.Unlift-      Core.Text-      Core.Text.Bytes-      Core.Text.Rope-      Core.Text.Utilities-      Core.System-      Core.System.Base-      Core.System.External-  other-modules:-      Core.Program.Context-      Core.Program.Signal-  hs-source-dirs:-      lib-  ghc-options: -Wall -Wwarn -fwarn-tabs-  build-depends:-      Cabal-    , aeson-    , async-    , base >=4.11 && <5-    , bytestring-    , chronologique-    , containers-    , deepseq-    , directory-    , exceptions-    , fingertree-    , hashable-    , hourglass-    , mtl-    , prettyprinter-    , prettyprinter-ansi-terminal-    , safe-exceptions-    , scientific-    , stm-    , template-haskell-    , terminal-size-    , text-    , text-short-    , transformers-    , unix-    , unordered-containers-    , vector-  default-language: Haskell2010--executable experiment-  main-is: SimpleExperiment.hs-  hs-source-dirs:-      tests-  ghc-options: -Wall -Wwarn -fwarn-tabs -threaded-  build-depends:-      Cabal-    , aeson-    , async-    , base >=4.11 && <5-    , bytestring-    , chronologique-    , containers-    , deepseq-    , directory-    , exceptions-    , fingertree-    , hashable-    , hourglass-    , mtl-    , prettyprinter-    , prettyprinter-ansi-terminal-    , safe-exceptions-    , scientific-    , stm-    , template-haskell-    , terminal-size-    , text-    , text-short-    , transformers-    , unbeliever-    , unix-    , unordered-containers-    , vector-  if flag(development)-    ghc-prof-options: -fprof-auto-top-    buildable: True-  else-    buildable: False-  default-language: Haskell2010--executable snippet-  main-is: Snippet.hs-  hs-source-dirs:-      tests-  ghc-options: -Wall -Wwarn -fwarn-tabs -threaded-  build-depends:-      Cabal-    , aeson-    , async-    , base >=4.11 && <5-    , bytestring-    , chronologique-    , containers-    , deepseq-    , directory-    , exceptions-    , fingertree-    , hashable-    , hourglass-    , mtl-    , prettyprinter-    , prettyprinter-ansi-terminal-    , safe-exceptions-    , scientific-    , stm-    , template-haskell-    , terminal-size-    , text-    , text-short-    , transformers-    , unbeliever-    , unix-    , unordered-containers-    , vector-  if flag(development)-    ghc-prof-options: -fprof-auto-top-    buildable: True-  else-    buildable: False-  default-language: Haskell2010+    exposed-modules:+        Core.Data+        Core.Data.Structures+        Core.Encoding+        Core.Encoding.Json+        Core.Program+        Core.Program.Arguments+        Core.Program.Execute+        Core.Program.Logging+        Core.Program.Metadata+        Core.Program.Unlift+        Core.Text+        Core.Text.Bytes+        Core.Text.Rope+        Core.Text.Utilities+        Core.System+        Core.System.Base+        Core.System.External+    hs-source-dirs: lib+    other-modules:+        Core.Program.Context+        Core.Program.Signal+    default-language: Haskell2010+    ghc-options: -Wall -Wwarn -fwarn-tabs+    build-depends:+        Cabal >=2.4.1.0 && <2.5,+        aeson >=1.4.2.0 && <1.5,+        async >=2.2.1 && <2.3,+        base >=4.11 && <5,+        bytestring >=0.10.8.2 && <0.11,+        chronologique >=0.3.1.1 && <0.4,+        containers >=0.6.0.1 && <0.7,+        deepseq >=1.4.4.0 && <1.5,+        directory >=1.3.3.0 && <1.4,+        exceptions >=0.10.0 && <0.11,+        fingertree >=0.1.4.2 && <0.2,+        hashable >=1.2.7.0 && <1.3,+        hourglass >=0.2.12 && <0.3,+        mtl >=2.2.2 && <2.3,+        prettyprinter >=1.2.1 && <1.3,+        prettyprinter-ansi-terminal >=1.1.1.2 && <1.2,+        safe-exceptions >=0.1.7.0 && <0.2,+        scientific >=0.3.6.2 && <0.4,+        stm >=2.5.0.0 && <2.6,+        template-haskell >=2.14.0.0 && <2.15,+        terminal-size >=0.3.2.1 && <0.4,+        text >=1.2.3.1 && <1.3,+        text-short >=0.1.2 && <0.2,+        transformers >=0.5.6.2 && <0.6,+        unix >=2.7.2.2 && <2.8,+        unordered-containers >=0.2.9.0 && <0.3,+        vector >=0.12.0.2 && <0.13  test-suite check-  type: exitcode-stdio-1.0-  main-is: TestSuite.hs-  other-modules:-      CheckArgumentsParsing-      CheckBytesBehaviour-      CheckContainerBehaviour-      CheckJsonWrapper-      CheckProgramMonad-      CheckRopeBehaviour-  hs-source-dirs:-      tests-  ghc-options: -Wall -Wwarn -fwarn-tabs -threaded-  build-depends:-      Cabal-    , aeson-    , async-    , base >=4.11 && <5-    , bytestring-    , chronologique-    , containers-    , deepseq-    , directory-    , exceptions-    , fingertree-    , hashable-    , hourglass-    , hspec-    , mtl-    , prettyprinter-    , prettyprinter-ansi-terminal-    , safe-exceptions-    , scientific-    , stm-    , template-haskell-    , terminal-size-    , text-    , text-short-    , transformers-    , unbeliever-    , unix-    , unordered-containers-    , vector-  default-language: Haskell2010+    type: exitcode-stdio-1.0+    main-is: TestSuite.hs+    hs-source-dirs: tests+    other-modules:+        CheckArgumentsParsing+        CheckBytesBehaviour+        CheckContainerBehaviour+        CheckJsonWrapper+        CheckProgramMonad+        CheckRopeBehaviour+    default-language: Haskell2010+    ghc-options: -Wall -Wwarn -fwarn-tabs -threaded+    build-depends:+        Cabal >=2.4.1.0 && <2.5,+        aeson >=1.4.2.0 && <1.5,+        async >=2.2.1 && <2.3,+        base >=4.11 && <5,+        bytestring >=0.10.8.2 && <0.11,+        chronologique >=0.3.1.1 && <0.4,+        containers >=0.6.0.1 && <0.7,+        deepseq >=1.4.4.0 && <1.5,+        directory >=1.3.3.0 && <1.4,+        exceptions >=0.10.0 && <0.11,+        fingertree >=0.1.4.2 && <0.2,+        hashable >=1.2.7.0 && <1.3,+        hourglass >=0.2.12 && <0.3,+        hspec >=2.6.1 && <2.7,+        mtl >=2.2.2 && <2.3,+        prettyprinter >=1.2.1 && <1.3,+        prettyprinter-ansi-terminal >=1.1.1.2 && <1.2,+        safe-exceptions >=0.1.7.0 && <0.2,+        scientific >=0.3.6.2 && <0.4,+        stm >=2.5.0.0 && <2.6,+        template-haskell >=2.14.0.0 && <2.15,+        terminal-size >=0.3.2.1 && <0.4,+        text >=1.2.3.1 && <1.3,+        text-short >=0.1.2 && <0.2,+        transformers >=0.5.6.2 && <0.6,+        unbeliever -any,+        unix >=2.7.2.2 && <2.8,+        unordered-containers >=0.2.9.0 && <0.3,+        vector >=0.12.0.2 && <0.13  benchmark performance-  type: exitcode-stdio-1.0-  main-is: GeneralPerformance.hs-  hs-source-dirs:-      bench-  ghc-options: -Wall -Wwarn -fwarn-tabs -threaded-  build-depends:-      Cabal-    , aeson-    , async-    , base >=4.11 && <5-    , bytestring-    , chronologique-    , containers-    , deepseq-    , directory-    , exceptions-    , fingertree-    , gauge-    , hashable-    , hourglass-    , mtl-    , prettyprinter-    , prettyprinter-ansi-terminal-    , safe-exceptions-    , scientific-    , stm-    , template-haskell-    , terminal-size-    , text-    , text-short-    , transformers-    , unbeliever-    , unix-    , unordered-containers-    , vector-  default-language: Haskell2010+    type: exitcode-stdio-1.0+    main-is: GeneralPerformance.hs+    hs-source-dirs: bench+    default-language: Haskell2010+    ghc-options: -Wall -Wwarn -fwarn-tabs -threaded+    build-depends:+        Cabal >=2.4.1.0 && <2.5,+        aeson >=1.4.2.0 && <1.5,+        async >=2.2.1 && <2.3,+        base >=4.11 && <5,+        bytestring >=0.10.8.2 && <0.11,+        chronologique >=0.3.1.1 && <0.4,+        containers >=0.6.0.1 && <0.7,+        deepseq >=1.4.4.0 && <1.5,+        directory >=1.3.3.0 && <1.4,+        exceptions >=0.10.0 && <0.11,+        fingertree >=0.1.4.2 && <0.2,+        gauge >=0.2.4 && <0.3,+        hashable >=1.2.7.0 && <1.3,+        hourglass >=0.2.12 && <0.3,+        mtl >=2.2.2 && <2.3,+        prettyprinter >=1.2.1 && <1.3,+        prettyprinter-ansi-terminal >=1.1.1.2 && <1.2,+        safe-exceptions >=0.1.7.0 && <0.2,+        scientific >=0.3.6.2 && <0.4,+        stm >=2.5.0.0 && <2.6,+        template-haskell >=2.14.0.0 && <2.15,+        terminal-size >=0.3.2.1 && <0.4,+        text >=1.2.3.1 && <1.3,+        text-short >=0.1.2 && <0.2,+        transformers >=0.5.6.2 && <0.6,+        unbeliever -any,+        unix >=2.7.2.2 && <2.8,+        unordered-containers >=0.2.9.0 && <0.3,+        vector >=0.12.0.2 && <0.13