-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Convenience wrappers around common data structures and encodings -- -- Wrappers around common data structures and encodings. -- -- This is part of a library intended to ease interoperability and assist -- in building command-line programs, both tools and longer-running -- daemons. A list of features and some background to the library's -- design is contained in the README on GitHub. @package core-data @version 0.3.9.0 -- | The standard package for working with dates and times in Haskell, -- time, is awkward. That's a subjective judgment, but over -- the years there have been few areas more frustrating than trying to do -- pragmatic things with calendars and clocks. This module represents -- some opinionated approaches to working with times and dates, and a -- place to collect some hard-won idioms for converting between things. -- -- Our original use was wanting to conveniently measure things happening -- on distributed computer systems. Since machine clock cycles are in -- units of nanoseconds, this has the nice property that, assuming the -- system clock is not corrupted, two subsequent events from the same -- source process are likely to have monotonically increasing timestamps. -- And even if the system clock goes to hell, they're still decently -- likely to be unique per device. Make for good keys. -- -- So the timestamp type herein Time is nanoseconds since the Unix -- epoch; which in (signed) 64 bits means that you can represent times -- between early in the morning of 21 September 1677 through just before -- midnight on 11 April 2262. The primary use isn't doing calendaring, -- though; it's just working with machine generated timestamps in -- distributed systems and for conveying start and end times around in -- your program. -- -- There are quite a few other time formats around the Haskell ecosystem. -- You can use the fromTime and intoTime methods of the -- Instant typeclass to convert from one to another if you need -- to. module Core.Data.Clock -- | Number of nanoseconds since the Unix epoch. -- -- The Show and Externalize instances display the -- Time as seconds with the nanosecond precision expressed as a -- decimal amount after the interger, ie: -- --
--   >>> t <- getCurrentTimeNanoseconds
--   
--   >>> formatExternal t
--   "2014-07-31T23:09:35.274387031Z"
--   
-- -- However this doesn't change the fact the underlying representation -- counts nanoseconds since epoch: -- --
--   >>> show $ unTime t
--   "1406848175274387031"
--   
-- -- There is a Externalize instance that is reasonably -- accommodating: -- --
--   >>> parseExternal "2014-07-31T13:05:04.942089001Z" :: Maybe Time
--   Just 2014-07-31T13:05:04.942089001Z
--   
-- --
--   >>> parseExternal "1406811904.942089001" :: Maybe Time
--   Just 2014-07-31T13:05:04.942089001Z
--   
-- --
--   >>> parseExternal "1406811904" :: Maybe Time
--   Just 2014-07-31T13:05:04.000000000Z
--   
-- -- In case you're wondering, the valid range of nanoseconds that fits -- into the underlying Int64 is: -- --
--   >>> formatExternal (minBound :: Time)
--   "1677-09-21T00:12:43.145224192Z"
--   
-- --
--   >>> formatExternal (maxBound :: Time)
--   "2262-04-11T23:47:16.854775807Z"
--   
-- -- so in a quarter millenium's time, yes, you'll have the Y2262 Problem. -- Haskell code from today will, of course, still be running, so in the -- mid Twenty-Third century you will need to replace this implementation -- with something else. data Time -- | Get the current system time, expressed as a Time (which is to -- say, number of nanoseconds since the Unix epoch). getCurrentTimeNanoseconds :: IO Time -- | Convert between different representations of time. Our Time -- timestamp has nanosecond precision so converting from a type with -- lesser or greater precision will require you to either pad with zeros -- or to round to the nearest nanosecond (who the hell has picoseconds of -- anything anyway?) if writing an instance of this type. -- -- The most important instance is probably the UTCTime one, as -- many other Haskell libraries use this type to represent time. class Instant a fromTime :: Instant a => Time -> a intoTime :: Instant a => a -> Time -- | If you need to manipulate the date or calculate elapsed time then you -- can dig out the underlying Int64 here. We have not -- provided instances of Num, Real, or Integral for -- the timestamp type because adding two timestamps doesn't really make -- sense. You can use intoTime to reconstruct a timestamp -- subsequently if necessary. unTime :: Time -> Int64 -- | The occasion of the Unix epoch, 1970-01-01T00:00:00.0Z. epochTime :: Time instance GHC.Generics.Generic Core.Data.Clock.Time instance GHC.Enum.Bounded Core.Data.Clock.Time instance GHC.Enum.Enum Core.Data.Clock.Time instance GHC.Classes.Ord Core.Data.Clock.Time instance GHC.Classes.Eq Core.Data.Clock.Time instance Core.Data.Clock.Instant GHC.Int.Int64 instance Core.Data.Clock.Instant Data.Time.Clock.Internal.UTCTime.UTCTime instance Core.Data.Clock.Instant Data.Time.Clock.Internal.POSIXTime.POSIXTime instance Core.Data.Clock.Instant Time.Types.ElapsedP instance Core.Data.Clock.Instant Data.Time.Calendar.Days.Day instance GHC.Show.Show Core.Data.Clock.Time instance GHC.Read.Read Core.Data.Clock.Time instance Data.Aeson.Types.ToJSON.ToJSON Core.Data.Clock.Time instance Data.Aeson.Types.FromJSON.FromJSON Core.Data.Clock.Time -- | Convenience wrappers around dictionary and collection types and tools -- facilitating conversion between them and various map and set types in -- common use in the Haskell ecosystem. module Core.Data.Structures -- | A mapping from keys to values. -- -- The keys in a map needs to be an instance of the Key typeclass. -- Instances are already provided for many common element types. -- -- Map implements Foldable, Monoid, etc so many -- common operations such as foldr to reduce the structure with a -- right fold, length to get the number of key/value pairs in the -- dictionary, null to test whether the map is empty, and -- (<>) to join two maps together are available. -- -- To convert to other dictionary types see fromMap below. -- -- (this is a thin wrapper around unordered-containers's -- HashMap, but if you use the conversion functions to extract the -- key/value pairs in a list the list will be ordered according to the -- keys' Ord instance) data Map κ ν -- | A dictionary with no key/value mappings. emptyMap :: Map κ ν -- | Construct a dictionary with only a single key/value pair. singletonMap :: Key κ => κ -> ν -> Map κ ν -- | Insert a key/value pair into the dictionary. If the key is already -- present in the dictionary, the old value will be discarded and -- replaced with the value supplied here. insertKeyValue :: Key κ => κ -> ν -> Map κ ν -> Map κ ν -- | Does the dictionary contain the specified key? containsKey :: Key κ => κ -> Map κ ν -> Bool -- | If the dictionary contains the specified key, return the value -- associated with that key. lookupKeyValue :: Key κ => κ -> Map κ ν -> Maybe ν -- | Remove a key/value pair if present in the dictionary. removeKeyValue :: Key κ => κ -> Map κ ν -> Map κ ν -- | Types that represent key/value pairs that can be converted to -- Maps. Haskell's ecosystem has several such. This typeclass -- provides an adaptor to get between them. It also allows you to -- serialize out to an association list. -- -- For example, to convert a Map to an "association list" of -- key/value pairs, use fromMap: -- --
--   answers :: Map Rope Int
--   answers = singletonMap "Life, The Universe, and Everything" 42
--   
--   list :: [(Rope,Int)]
--   list = fromMap answers
--   
-- -- Instances are provided for containers's Map and -- unordered-containers's HashMap in addition to the -- instance for [(κ,ν)] lists shown above. class Dictionary α where { type K α :: Type; type V α :: Type; } fromMap :: Dictionary α => Map (K α) (V α) -> α intoMap :: Dictionary α => α -> Map (K α) (V α) -- | A set of unique elements. -- -- The element type needs to be an instance of the same Key -- typeclass that is used for keys in the Map type above. -- Instances are already provided for many common element types. -- -- Set implements Foldable, Monoid, etc so many -- common operations such as foldr to walk the elements and reduce -- them, length to return the size of the collection, null -- to test whether is empty, and (<>) to take the union of -- two sets are available. -- -- To convert to other collection types see fromSet below. -- -- (this is a thin wrapper around unordered-containers's -- HashSet, but if you use the conversion functions to extract a -- list the list will be ordered according to the elements' Ord -- instance) data Set ε -- | An empty collection. This is used for example as an inital value when -- building up a Set using a fold. emptySet :: Key ε => Set ε -- | Construct a collection comprising only the supplied element. singletonSet :: Key ε => ε -> Set ε -- | Insert a new element into the collection. Since the Set type -- does not allow duplicates, inserting an element already in the -- collection has no effect. insertElement :: Key ε => ε -> Set ε -> Set ε -- | Does the collection contain the specified element? containsElement :: Key ε => ε -> Set ε -> Bool -- | Remove an element from the collection if present. removeElement :: Key ε => ε -> Set ε -> Set ε -- | Types that represent collections of elements that can be converted to -- Sets. Haskell's ecosystem has several such. This typeclass -- provides an adaptor to convert between them. -- -- This typeclass also provides a mechanism to serialize a Set out -- to a Haskell list. The list will be ordered according to the -- Ord instance of the element type. -- -- Instances are provided for containers's Set and -- unordered-containers's HashSet in addition to the -- instance for [ε] lists described above. class Collection α where { type E α :: Type; } fromSet :: Collection α => Set (E α) -> α intoSet :: Collection α => α -> Set (E α) -- | Types that can be used as keys in dictionaries or elements in -- collections. -- -- To be an instance of Key a type must implement both -- Hashable and Ord. This requirement means we can -- subsequently offer easy conversion between different the dictionary -- and collection types you might encounter when interacting with other -- libraries. -- -- Instances for this library's Rope and Bytes are provided -- here, along with many other common types. class (Hashable κ, Ord κ) => Key κ unMap :: Map κ ν -> HashMap κ ν unSet :: Set ε -> HashSet ε instance Data.Bifoldable.Bifoldable Core.Data.Structures.Map instance (GHC.Classes.Eq κ, GHC.Classes.Eq ν) => GHC.Classes.Eq (Core.Data.Structures.Map κ ν) instance (GHC.Show.Show κ, GHC.Show.Show ν) => GHC.Show.Show (Core.Data.Structures.Map κ ν) instance GHC.Classes.Eq ε => GHC.Classes.Eq (Core.Data.Structures.Set ε) instance GHC.Show.Show ε => GHC.Show.Show (Core.Data.Structures.Set ε) instance Core.Data.Structures.Key ε => Core.Data.Structures.Collection (Core.Data.Structures.Set ε) instance Core.Data.Structures.Key ε => Core.Data.Structures.Collection (Data.HashSet.Internal.HashSet ε) instance Core.Data.Structures.Key ε => Core.Data.Structures.Collection (Data.Set.Internal.Set ε) instance Core.Data.Structures.Key ε => Core.Data.Structures.Collection [ε] instance Data.Foldable.Foldable Core.Data.Structures.Set instance Core.Data.Structures.Key ε => GHC.Base.Semigroup (Core.Data.Structures.Set ε) instance Core.Data.Structures.Key ε => GHC.Base.Monoid (Core.Data.Structures.Set ε) instance Core.Data.Structures.Key κ => Core.Data.Structures.Dictionary (Core.Data.Structures.Map κ ν) instance Core.Data.Structures.Key κ => Core.Data.Structures.Dictionary (Data.HashMap.Internal.HashMap κ ν) instance Core.Data.Structures.Key κ => Core.Data.Structures.Dictionary (Data.Map.Internal.Map κ ν) instance Core.Data.Structures.Key κ => Core.Data.Structures.Dictionary [(κ, ν)] instance Core.Data.Structures.Key GHC.Base.String instance Core.Data.Structures.Key Core.Text.Rope.Rope instance Core.Data.Structures.Key Core.Text.Bytes.Bytes instance Core.Data.Structures.Key Data.Text.Internal.Text instance Core.Data.Structures.Key Data.Text.Internal.Lazy.Text instance Core.Data.Structures.Key GHC.Types.Char instance Core.Data.Structures.Key GHC.Types.Int instance Core.Data.Structures.Key Data.ByteString.Internal.ByteString instance Core.Data.Structures.Key GHC.Conc.Sync.ThreadId instance Core.Data.Structures.Key κ => GHC.Base.Semigroup (Core.Data.Structures.Map κ ν) instance Core.Data.Structures.Key κ => GHC.Base.Monoid (Core.Data.Structures.Map κ ν) instance Core.Data.Structures.Key κ => GHC.Exts.IsList (Core.Data.Structures.Map κ ν) instance Data.Foldable.Foldable (Core.Data.Structures.Map κ) -- | Wrappers and adaptors for various data structures common in the -- Haskell ecosystem. -- -- This is intended to be used directly: -- --
--   import Core.Data
--   
-- -- as this module re-exports all of its various components. module Core.Data -- | Quite frequently you will find yourself needing to convert between a -- rich semantic Haskell data type and a textual representation of that -- type which we call the external representation of a value. The -- external representation of the value is authoriative and is meant to -- be re-readable even in the face of changing implemetations on the -- program side. -- -- Note that externalizing is not quite the same as -- serializing. If you have more complex data structures (ie rich -- types or nesting) then a simple text string will probably not be -- sufficient to convey sufficient information to represent it -- accurately. Serializing is focused on both performance encoding and -- decoding, and efficiency of the representation when transmitted over -- the wire. Of course, the obvious benefits of efficiency didn't stop -- the entire computer industry from near universal adoption of JSON as -- an interchange format, so there is, perhaps, no hope for us. -- -- You can, however, regain some of your sanity by ensuring that the -- individual fields of a larger structure are safe, and that's where the -- externalizing machinery in this module comes in. -- -- If you have read this far and think we are describing something -- similar to Haskell's Show, Python's repr() or Java's -- toString() you would be correct, but at the level of -- primative and simple types we are providing the ability to marshall -- them to a clean UTF-8 representation and to unmarshall them back into -- Haskell values again. -- -- The other major use case for this module is as a helper to read user -- input; see queryOptionValue' for an example that makes use of -- this. -- -- Notes for implementators -- -- Postel's dictum to "be conservative in what you produce but liberal in -- what you accept" describes the intent of this module. If you are -- implementing an instance of Externalize then you might consider -- being flexible as possible when parsing with parseExternal, -- within the constraints of having to read a given value with exact -- fidelity. But when outputing a value with formatExternal you -- should be correcting the representation of the value to a canonical, -- stable form, even if the original input was written differently. See -- the discussion of creating Time types from varying inputs for -- an example. module Core.Encoding.External -- | Convert between the internal Haskell representation of a data type and -- an external, textual form suitable for visualization, onward -- transmission, or archival storage. -- -- It is expected that a valid instance of Externalize allows you -- to round-trip through it: -- --
--   >>> formatExternal (42 :: Int))
--   "42"
--   
-- --
--   >>> fromJust (parseExternal "42") :: Int
--   42
--   
-- -- with the usual caveat about needing to ensure you've given enough -- information to the type-checker to know which instance you're asking -- for. -- -- There is a general implementatation that goes though Show and -- Read via String but if you know you have a direct way to -- render or parse a type into a sequence of characters then you can -- offer an instance of Externalize which does so more -- efficiently. class Externalize ξ -- | Convert a value into an authoritative, stable textual representation -- for use externally. formatExternal :: Externalize ξ => ξ -> Rope -- | Attempt to read an external textual representation into a Haskell -- value. parseExternal :: Externalize ξ => Rope -> Maybe ξ instance (GHC.Read.Read a, GHC.Show.Show a) => Core.Encoding.External.Externalize a instance Core.Encoding.External.Externalize Core.Text.Rope.Rope instance Core.Encoding.External.Externalize GHC.Base.String instance Core.Encoding.External.Externalize GHC.Types.Int instance Core.Encoding.External.Externalize GHC.Int.Int8 instance Core.Encoding.External.Externalize GHC.Int.Int16 instance Core.Encoding.External.Externalize GHC.Int.Int32 instance Core.Encoding.External.Externalize GHC.Int.Int64 instance Core.Encoding.External.Externalize GHC.Word.Word8 instance Core.Encoding.External.Externalize GHC.Word.Word16 instance Core.Encoding.External.Externalize GHC.Word.Word32 instance Core.Encoding.External.Externalize GHC.Word.Word64 instance Core.Encoding.External.Externalize GHC.Types.Float instance Core.Encoding.External.Externalize GHC.Types.Double instance Core.Encoding.External.Externalize Data.UUID.Types.Internal.UUID instance Core.Encoding.External.Externalize Core.Data.Clock.Time instance Core.Encoding.External.Externalize Data.Time.Calendar.Days.Day instance Core.Encoding.External.Externalize Data.Scientific.Scientific -- | Encoding and decoding UTF-8 JSON content. -- -- This module is a thin wrapper around the most excellent aeson -- library, which has rich and powerful facilities for encoding Haskell -- types into JSON. -- -- Quite often, however, you find yourself having to create a Haskell -- type just to read some JSON coming from an external web service -- or API. This can be challenging when the source of the JSON is complex -- or varying its schema over time. For ease of exploration this module -- simply defines an easy to use intermediate type representing JSON as a -- format. -- -- Often you'll be working with literals directly in your code. While you -- can write: -- --
--   j = JsonObject (intoMap [(JsonKey "answer", JsonNumber 42)])
--   
-- -- and it would be correct, enabling: -- --
--   {-# LANGUAGE OverloadedStrings #-}
--   {-# LANGUAGE OverloadedLists #-}
--   
-- -- allows you to write: -- --
--   j = JsonObject [("answer", 42)]
--   
-- -- which you is somewhat less cumbersome in declaration-heavy code. -- You're certainly welcome to use the constructors if you find it makes -- for more readable code or if you need the type annotations. module Core.Encoding.Json -- | Given a JSON value, encode it to UTF-8 bytes -- -- I know we're not supposed to rely on types to document -- functions, but really, this one does what it says on the tin. encodeToUTF8 :: JsonValue -> Bytes -- | Given a JSON value, encode it to a Rope (which, by definition, is -- UTF-8 internally). encodeToRope :: JsonValue -> Rope -- | Given an array of bytes, attempt to decode it as a JSON value. decodeFromUTF8 :: Bytes -> Maybe JsonValue -- | Given an string that is full of a bunch of JSON, attempt to decode it. decodeFromRope :: Rope -> Maybe JsonValue -- | A JSON value. data JsonValue JsonObject :: Map JsonKey JsonValue -> JsonValue JsonArray :: [JsonValue] -> JsonValue JsonString :: Rope -> JsonValue JsonNumber :: Scientific -> JsonValue JsonBool :: Bool -> JsonValue JsonNull :: JsonValue -- | Keys in a JSON object. newtype JsonKey JsonKey :: Rope -> JsonKey -- | Support for pretty-printing JSON values with syntax highlighting using -- the prettyprinter library. To output a JSON structure to -- terminal colourized with ANSI escape codes you can use the -- Render instance: -- --
--   debug "j" (render j)
--   
-- -- will get you: -- --
--   23:46:04Z (00.007) j =
--   {
--       "answer": 42
--   }
--   
data JsonToken SymbolToken :: JsonToken QuoteToken :: JsonToken KeyToken :: JsonToken StringToken :: JsonToken EscapeToken :: JsonToken NumberToken :: JsonToken BooleanToken :: JsonToken LiteralToken :: JsonToken -- | Used by the Render instance to turn symbolic annotations into -- ANSI colours annotations. If you're curious, the render pipeline looks -- like: -- --
--   render = intoText . renderStrict . reAnnotateS colourize
--               . layoutPretty defaultLayoutOptions . prettyValue
--   
colourizeJson :: JsonToken -> AnsiColour prettyKey :: JsonKey -> Doc JsonToken prettyValue :: JsonValue -> Doc JsonToken instance GHC.Classes.Ord Core.Encoding.Json.JsonKey instance Data.String.IsString Core.Encoding.Json.JsonKey instance GHC.Generics.Generic Core.Encoding.Json.JsonKey instance GHC.Show.Show Core.Encoding.Json.JsonKey instance GHC.Classes.Eq Core.Encoding.Json.JsonKey instance GHC.Generics.Generic Core.Encoding.Json.JsonValue instance GHC.Show.Show Core.Encoding.Json.JsonValue instance GHC.Classes.Eq Core.Encoding.Json.JsonValue instance Core.Text.Utilities.Render Core.Encoding.Json.JsonValue instance Core.Text.Utilities.Render Core.Encoding.Json.JsonKey instance Data.String.IsString Core.Encoding.Json.JsonValue instance GHC.Num.Num Core.Encoding.Json.JsonValue instance GHC.Real.Fractional Core.Encoding.Json.JsonValue instance Prettyprinter.Internal.Pretty Core.Encoding.Json.JsonValue instance Data.Hashable.Class.Hashable Core.Encoding.Json.JsonKey instance Core.Data.Structures.Key Core.Encoding.Json.JsonKey instance Core.Text.Rope.Textual Core.Encoding.Json.JsonKey instance Prettyprinter.Internal.Pretty Core.Encoding.Json.JsonKey instance Data.Aeson.Types.FromJSON.FromJSON Core.Text.Rope.Rope -- | Various formats used for serialization, data transfer, and -- configuration. -- -- This can be used by simply importing the top level module: -- --
--   import Core.Encoding
--   
-- -- although the individual formats are quite usable indepedently. -- -- Each of these encodings are backed by a popular and well tuned library -- in wide use across the Haskell community; these modules are here as -- wrappers providing for ease of use and interoperability across the -- various tools in this package. module Core.Encoding