dhall 1.15.0 → 1.15.1
raw patch · 5 files changed
+142/−92 lines, 5 filesdep +mockerydep ~contravariantdep ~criteriondep ~directoryPVP ok
version bump matches the API change (PVP)
Dependencies added: mockery
Dependency ranges changed: contravariant, criterion, directory, filepath
API changes (from Hackage documentation)
Files
- CHANGELOG.md +5/−0
- dhall.cabal +9/−7
- doctest/Main.hs +24/−1
- src/Dhall/Pretty/Internal.hs +13/−1
- src/Dhall/Tutorial.hs +91/−83
CHANGELOG.md view
@@ -1,3 +1,8 @@+1.15.1++* Fix infinite loop when formatting expressions containing `?`+ * See: https://github.com/dhall-lang/dhall-haskell/pull/491+ 1.15.0 * BREAKING CHANGE TO THE API: Support alternative imports using new `?` operator
dhall.cabal view
@@ -1,5 +1,5 @@ Name: dhall-Version: 1.15.0+Version: 1.15.1 Cabal-Version: >=1.10 Build-Type: Simple Tested-With: GHC == 8.0.1@@ -173,7 +173,7 @@ bytestring < 0.11, case-insensitive < 1.3 , containers >= 0.5.0.0 && < 0.6 ,- contravariant < 1.5 ,+ contravariant < 1.6 , cryptonite >= 0.23 && < 1.0 , Diff >= 0.2 && < 0.4 , directory >= 1.3 && < 1.4 ,@@ -274,9 +274,11 @@ Main-Is: Main.hs GHC-Options: -Wall Build-Depends:- base ,- Diff >= 0.2 && < 0.4 ,- doctest >= 0.7.0 && < 0.16+ base ,+ directory >= 1.2.2.0 && < 1.4 ,+ filepath < 1.5 ,+ mockery < 0.4 ,+ doctest >= 0.7.0 && < 0.17 Default-Language: Haskell2010 Benchmark dhall-parser@@ -285,7 +287,7 @@ Build-Depends: base >= 4 && < 5 , containers >= 0.5.0.0 && < 0.6,- criterion >= 1.1 && < 1.5,+ criterion >= 1.1 && < 1.6, dhall , directory >= 1.3 && < 1.4, text >= 0.11.1.0 && < 1.3@@ -297,6 +299,6 @@ Build-Depends: base >= 4 && < 5 , containers >= 0.5.0.0 && < 0.6,- criterion >= 1.1 && < 1.5,+ criterion >= 1.1 && < 1.6, dhall Default-Language: Haskell2010
doctest/Main.hs view
@@ -1,6 +1,29 @@ module Main where +import Data.Monoid ((<>))+import System.FilePath ((</>))++import qualified System.Directory+import qualified Test.Mockery.Directory import qualified Test.DocTest main :: IO ()-main = Test.DocTest.doctest [ "-isrc", "src/Dhall.hs", "src/Dhall/Import.hs" ]+main = do+ pwd <- System.Directory.getCurrentDirectory+ prefix <- System.Directory.makeAbsolute pwd++ Test.Mockery.Directory.inTempDirectory $ do+ writeFile "makeBools" "λ(n : Bool) → [ n && True, n && False, n || True, n || False ]"+ writeFile "bool1" "True"+ writeFile "bool2" "False"+ writeFile "both" "./bool1 && ./bool2"+ writeFile "file2" "./file1"+ writeFile "file1" "./file2"++ Test.DocTest.doctest+ [ "--fast"+ , "-i" <> (prefix </> "src")+ , prefix </> "src/Dhall.hs"+ , prefix </> "src/Dhall/Import.hs"+ , prefix </> "src/Dhall/Tutorial.hs"+ ]
src/Dhall/Pretty/Internal.hs view
@@ -541,7 +541,19 @@ prettyOperatorExpression a0 prettyOperatorExpression :: Pretty a => Expr s a -> Doc Ann-prettyOperatorExpression = prettyOrExpression+prettyOperatorExpression = prettyImportAltExpression++prettyImportAltExpression :: Pretty a => Expr s a -> Doc Ann+prettyImportAltExpression a0@(ImportAlt _ _) =+ enclose' "" " " (space <> operator "?" <> space) (operator "?" <> " ") (fmap duplicate (docs a0))+ where+ docs (ImportAlt a b) = prettyOrExpression a : docs b+ docs (Note _ b) = docs b+ docs b = [ prettyOrExpression b ]+prettyImportAltExpression (Note _ a) =+ prettyImportAltExpression a+prettyImportAltExpression a0 =+ prettyOrExpression a0 prettyOrExpression :: Pretty a => Expr s a -> Doc Ann prettyOrExpression a0@(BoolOr _ _) =
src/Dhall/Tutorial.hs view
@@ -168,6 +168,10 @@ import Data.Vector (Vector) import Dhall +-- $setup+--+-- >>> :set -XOverloadedStrings+ -- $introduction -- -- The simplest way to use Dhall is to ignore the programming language features@@ -208,9 +212,9 @@ -- You can also load some types directly into Haskell without having to define a -- record, like this: ----- > >>> :set -XOverloadedStrings--- > >>> input auto "True" :: IO Bool--- > True+-- >>> :set -XOverloadedStrings+-- >>> input auto "True" :: IO Bool+-- True -- -- The `input` function can decode any value if we specify the value's expected -- `Type`:@@ -227,20 +231,20 @@ -- > input bool :: Text -> IO Bool -- > -- > input bool "True" :: IO Bool--- >--- > >>> input bool "True"--- > True --+-- >>> input bool "True"+-- True+-- -- ... or we can use `auto` to let the compiler infer what type to decode from -- the expected return type: -- -- > auto :: Interpret a => Type a -- > -- > input auto :: Interpret a => Text -> IO a--- >--- > >>> input auto "True" :: IO Bool--- > True --+-- >>> input auto "True" :: IO Bool+-- True+-- -- You can see what types `auto` supports \"out-of-the-box\" by browsing the -- instances for the `Interpret` class. For example, the following instance -- says that we can directly decode any Dhall expression that evaluates to a@@ -259,14 +263,14 @@ -- Therefore, since we can decode a @Bool@, we must also be able to decode a -- @List@ of @Bool@s, like this: ----- > >>> input auto "[True, False]" :: IO (Vector Bool)--- > [True,False]+-- >>> input auto "[True, False]" :: IO (Vector Bool)+-- [True,False] -- -- We could also specify what type to decode by providing an explicit `Type` -- instead of using `auto` with a type annotation: ----- > >>> input (vector bool) "[True, False]"--- > [True, False]+-- >>> input (vector bool) "[True, False]"+-- [True,False] -- -- __Exercise:__ Create a @./config@ file that the following program can decode: --@@ -303,16 +307,17 @@ -- -- Suppose that we try to decode a value of the wrong type, like this: ----- > >>> input auto "1" :: IO Bool--- > *** Exception:--- > Error: Expression doesn't match annotation--- > --- > - Bool--- > + Natural--- > --- > 1 : Bool--- > --- > (input):1:1+-- >>> input auto "1" :: IO Bool+-- *** Exception:+-- ...Error...: Expression doesn't match annotation+-- ...+-- - Bool+-- + Natural+-- ...+-- 1 : Bool+-- ...+-- (input):1:1+-- ... -- -- The interpreter complains because the string @\"1\"@ cannot be decoded into a -- Haskell value of type `Bool`. This part of the type error:@@ -364,14 +369,14 @@ -- -- You might wonder why in some cases we can decode a configuration file: ----- > >>> writeFile "bool" "True"--- > >>> input auto "./bool" :: IO Bool--- > True+-- >>> writeFile "bool" "True"+-- >>> input auto "./bool" :: IO Bool+-- True -- -- ... and in other cases we can decode a value directly: ----- > >>> input auto "True" :: IO Bool--- > True+-- >>> input auto "True" :: IO Bool+-- True -- -- This is because importing a configuration from a file is a special case of a -- more general language feature: Dhall expressions can reference other@@ -385,8 +390,8 @@ -- -- ... and read in all three files in a single expression: -- --- > >>> input auto "[ ./bool1 , ./bool2 , ./both ]" :: IO (Vector Bool)--- > [True,False,False]+-- >>> input auto "[ ./bool1 , ./bool2 , ./both ]" :: IO (Vector Bool)+-- [True,False,False] -- -- Each file path is replaced with the Dhall expression contained within that -- file. If that file contains references to other files then those references@@ -415,12 +420,12 @@ -- -- ... then the interpreter will reject the import: ----- > >>> input auto "./file1" :: IO Natural--- > *** Exception: --- > ↳ ./file1--- > ↳ ./file2--- >--- > Cyclic import: ./file1+-- >>> input auto "./file1" :: IO Natural+-- *** Exception: +-- ↳ ./file1+-- ↳ ./file2+-- ...+-- Cyclic import: ./file1 -- -- You can also import expressions by URL. For example, you can find a Dhall -- expression hosted at this GitHub URL:@@ -432,13 +437,13 @@ -- -- ... and you can reference that expression either directly: ----- > >>> input auto "https://raw.githubusercontent.com/dhall-lang/dhall-haskell/18e4e9a18dc53271146df3ccf5b4177c3552236b/examples/True" :: IO Bool--- > True+-- >>> input auto "https://raw.githubusercontent.com/dhall-lang/dhall-haskell/18e4e9a18dc53271146df3ccf5b4177c3552236b/examples/True" :: IO Bool+-- True -- -- ... or inside of a larger expression: ----- > >>> input auto "False == https://raw.githubusercontent.com/dhall-lang/dhall-haskell/18e4e9a18dc53271146df3ccf5b4177c3552236b/examples/True" :: IO Bool--- > False+-- >>> input auto "False == https://raw.githubusercontent.com/dhall-lang/dhall-haskell/18e4e9a18dc53271146df3ccf5b4177c3552236b/examples/True" :: IO Bool+-- False -- -- You're not limited to hosting Dhall expressions on GitHub. You can host a -- Dhall expression anywhere that you can host UTF8-encoded text on the web,@@ -446,9 +451,9 @@ -- -- You can also import Dhall expressions from environment variables, too: ----- > >>> System.Environment.setEnv "FOO" "1"--- > >>> input auto "env:FOO" :: IO Natural--- > 1+-- >>> System.Environment.setEnv "FOO" "1"+-- >>> input auto "env:FOO" :: IO Natural+-- 1 -- -- You can import types, too. For example, we can change our @./bar@ file to: --@@ -466,20 +471,21 @@ -- Note that all imports must be terminated by whitespace or you will get either -- an import error or a parse error, like this: ----- > >>> writeFile "baz" "2.0"--- > >>> input auto "./baz: Double" :: IO Double--- > *** Exception: --- > ↳ ./baz: --- > --- > Error: Missing file+-- >>> writeFile "baz" "2.0"+-- >>> input auto "./baz: Double" :: IO Double+-- *** Exception: +-- ↳ ./baz: +-- ...+-- ...Error...: Missing file .../baz:+-- ... -- -- This is because the parser thinks that @./baz:@ is a single token due to -- the missing whitespace before the colon and tries to import a file named -- @./baz:@, which does not exist. To fix the problem we have to add a space -- after @./baz@: ----- > >>> input auto "./baz : Double" :: IO Double--- > 2.0+-- >>> input auto "./baz : Double" :: IO Double+-- 2.0 -- -- __Exercise:__ There is a @not@ function hosted online here: --@@ -503,30 +509,32 @@ -- required for empty lists but optional for non-empty lists. You will get a -- type error if you provide an empty list without a type annotation: ----- > >>> input auto "[]" :: IO (Vector Natural)--- > *** Exception:--- > Error: Invalid input--- > --- > (input):1:3:--- > |--- > 1 | []--- > | ^--- > unexpected end of input--- > expecting ':' or whitespace+-- >>> input auto "[]" :: IO (Vector Natural)+-- *** Exception:+-- ...Error...: Invalid input+-- ...+-- (input):1:3:+-- |+-- 1 | []+-- | ^+-- unexpected end of input+-- expecting ':' or whitespace+-- ... -- -- Also, list elements must all have the same type. You will get an error if -- you try to store elements of different types in a list: ----- > >>> input auto "[1, True, 3]" :: IO (Vector Natural)--- > *** Exception:--- > Error: List elements should all have the same type--- > --- > - Natural--- > + Bool--- > --- > True--- > --- > (input):1:5+-- >>> input auto "[1, True, 3]" :: IO (Vector Natural)+-- *** Exception:+-- ...Error...: List elements should all have the same type+-- ...+-- - Natural+-- + Bool+-- ...+-- True+-- ...+-- (input):1:5+-- ... -- -- __Exercise:__ What is the shortest @./config@ file that you can decode using -- this command:@@ -550,10 +558,10 @@ -- -- An @Optional@ corresponds to Haskell's `Maybe` type for decoding purposes: ----- > >>> input auto "[1] : Optional Natural" :: IO (Maybe Natural)--- > Just 1--- > >>> input auto "[] : Optional Natural" :: IO (Maybe Natural)--- > Nothing+-- >>> input auto "[1] : Optional Natural" :: IO (Maybe Natural)+-- Just 1+-- >>> input auto "[] : Optional Natural" :: IO (Maybe Natural)+-- Nothing -- -- You cannot omit the type annotation for @Optional@ values. The type -- annotation is mandatory@@ -612,8 +620,8 @@ -- ... which means to access the value of the field named @fieldName@ from the -- @record@. For example: ----- > >>> input auto "{ foo = True, bar = 2, baz = 4.2 }.baz" :: IO Double--- > 4.2+-- >>> input auto "{ foo = True, bar = 2, baz = 4.2 }.baz" :: IO Double+-- 4.2 -- -- ... and you can project out multiple fields into a new record using this -- syntax:@@ -809,8 +817,8 @@ -- Now that we've verified that our function type checks and works, we can use -- the same function within Haskell: ----- > >>> input auto "./makeBools True" :: IO (Vector Bool)--- > [True,False,True,True]+-- >>> input auto "./makeBools True" :: IO (Vector Bool)+-- [True,False,True,True] -- -- __Exercise__: Create a file named @getFoo@ that is a function of the following -- type:@@ -1226,10 +1234,10 @@ -- The identity function is polymorphic, meaning that `id` works on values of -- different types: ----- > >>> id 4--- > 4--- > >>> id True--- > True+-- >>> id 4+-- 4+-- >>> id True+-- True -- -- The equivalent function in Dhall is: --