Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new Dhall.Map module #612

Merged
merged 13 commits into from
Oct 6, 2018
Merged
11 changes: 11 additions & 0 deletions benchmark/deep-nested-large-record/Main.hs
Original file line number Diff line number Diff line change
@@ -30,9 +30,20 @@ issue412 prelude = Criterion.whnf TypeCheck.typeOf expr
$ Seq.replicate 5
$ Core.Var (Core.V "prelude" 0) `Core.Field` "types" `Core.Field` "Little" `Core.Field` "Foo"

unionPerformance :: Core.Expr s TypeCheck.X -> Criterion.Benchmarkable
unionPerformance prelude = Criterion.whnf TypeCheck.typeOf expr
where
expr =
Core.Let "x" Nothing
(Core.Let "big" Nothing (prelude `Core.Field` "types" `Core.Field` "Big")
(Core.Prefer "big" "big")
)
"x"

main :: IO ()
main = do
prelude <- Import.load (Core.Embed dhallPreludeImport)
defaultMain
[ Criterion.bench "issue 412" (issue412 prelude)
, Criterion.bench "union performance" (unionPerformance prelude)
]
9 changes: 3 additions & 6 deletions dhall.cabal
Original file line number Diff line number Diff line change
@@ -182,9 +182,7 @@ Library
directory >= 1.2.2.0 && < 1.4 ,
exceptions >= 0.8.3 && < 0.11,
filepath >= 1.4 && < 1.5 ,
hashable < 1.3 ,
haskeline >= 0.7.2.1 && < 0.8 ,
insert-ordered-containers >= 0.2.1.0 && < 0.3 ,
lens-family-core >= 1.0.0 && < 1.3 ,
megaparsec >= 7.0.0 && < 7.1 ,
memory >= 0.14 && < 0.15,
@@ -221,10 +219,11 @@ Library
Dhall.Hash,
Dhall.Import,
Dhall.Lint,
Dhall.Main
Dhall.Main,
Dhall.Map,
Dhall.Parser,
Dhall.Pretty,
Dhall.Repl
Dhall.Repl,
Dhall.TH,
Dhall.Tutorial,
Dhall.TypeCheck
@@ -270,8 +269,6 @@ Test-Suite tasty
containers ,
deepseq >= 1.2.0.1 && < 1.5 ,
dhall ,
hashable ,
insert-ordered-containers == 0.2.1.0 ,
prettyprinter ,
QuickCheck >= 2.10 && < 2.13,
quickcheck-instances >= 0.3.12 && < 0.4 ,
82 changes: 41 additions & 41 deletions src/Dhall.hs
Original file line number Diff line number Diff line change
@@ -114,7 +114,6 @@ import qualified Control.Monad.Trans.State.Strict as State
import qualified Data.Foldable
import qualified Data.Functor.Compose
import qualified Data.Functor.Product
import qualified Data.HashMap.Strict.InsOrd
import qualified Data.Scientific
import qualified Data.Sequence
import qualified Data.Set
@@ -126,6 +125,7 @@ import qualified Dhall.Binary
import qualified Dhall.Context
import qualified Dhall.Core
import qualified Dhall.Import
import qualified Dhall.Map
import qualified Dhall.Parser
import qualified Dhall.Pretty.Internal
import qualified Dhall.TypeCheck
@@ -708,10 +708,10 @@ unit :: Type ()
unit = Type extractOut expectedOut
where
extractOut (RecordLit fields)
| Data.HashMap.Strict.InsOrd.null fields = return ()
| Data.Foldable.null fields = return ()
extractOut _ = Nothing

expectedOut = Record Data.HashMap.Strict.InsOrd.empty
expectedOut = Record mempty

{-| Decode a `String`
@@ -731,13 +731,13 @@ pair :: Type a -> Type b -> Type (a, b)
pair l r = Type extractOut expectedOut
where
extractOut (RecordLit fields) =
(,) <$> ( Data.HashMap.Strict.InsOrd.lookup "_1" fields >>= extract l )
<*> ( Data.HashMap.Strict.InsOrd.lookup "_2" fields >>= extract r )
(,) <$> ( Dhall.Map.lookup "_1" fields >>= extract l )
<*> ( Dhall.Map.lookup "_2" fields >>= extract r )
extractOut _ = Nothing

expectedOut =
Record
(Data.HashMap.Strict.InsOrd.fromList
(Dhall.Map.fromList
[ ("_1", expected l)
, ("_2", expected r)
]
@@ -864,7 +864,7 @@ instance GenericInterpret V1 where
where
extract _ = Nothing

expected = Union Data.HashMap.Strict.InsOrd.empty
expected = Union mempty

instance (Constructor c1, Constructor c2, GenericInterpret f1, GenericInterpret f2) => GenericInterpret (M1 C c1 f1 :+: M1 C c2 f2) where
genericAutoWith options@(InterpretOptions {..}) = pure (Type {..})
@@ -885,7 +885,7 @@ instance (Constructor c1, Constructor c2, GenericInterpret f1, GenericInterpret
extract _ = Nothing

expected =
Union (Data.HashMap.Strict.InsOrd.fromList [(nameL, expectedL), (nameR, expectedR)])
Union (Dhall.Map.fromList [(nameL, expectedL), (nameR, expectedR)])

Type extractL expectedL = evalState (genericAutoWith options) 1
Type extractR expectedR = evalState (genericAutoWith options) 1
@@ -904,7 +904,7 @@ instance (Constructor c, GenericInterpret (f :+: g), GenericInterpret h) => Gene
extract _ = Nothing

expected =
Union (Data.HashMap.Strict.InsOrd.insert name expectedR expectedL)
Union (Dhall.Map.insert name expectedR expectedL)

Type extractL (Union expectedL) = evalState (genericAutoWith options) 1
Type extractR expectedR = evalState (genericAutoWith options) 1
@@ -923,7 +923,7 @@ instance (Constructor c, GenericInterpret f, GenericInterpret (g :+: h)) => Gene
extract _ = Nothing

expected =
Union (Data.HashMap.Strict.InsOrd.insert name expectedL expectedR)
Union (Dhall.Map.insert name expectedL expectedR)

Type extractL expectedL = evalState (genericAutoWith options) 1
Type extractR (Union expectedR) = evalState (genericAutoWith options) 1
@@ -933,7 +933,7 @@ instance (GenericInterpret (f :+: g), GenericInterpret (h :+: i)) => GenericInte
where
extract e = fmap L1 (extractL e) <|> fmap R1 (extractR e)

expected = Union (Data.HashMap.Strict.InsOrd.union expectedL expectedR)
expected = Union (Dhall.Map.union expectedL expectedR)

Type extractL (Union expectedL) = evalState (genericAutoWith options) 1
Type extractR (Union expectedR) = evalState (genericAutoWith options) 1
@@ -948,7 +948,7 @@ instance GenericInterpret U1 where
where
extract _ = Just U1

expected = Record (Data.HashMap.Strict.InsOrd.fromList [])
expected = Record (Dhall.Map.fromList [])

instance (GenericInterpret f, GenericInterpret g) => GenericInterpret (f :*: g) where
genericAutoWith options = do
@@ -959,7 +959,7 @@ instance (GenericInterpret f, GenericInterpret g) => GenericInterpret (f :*: g)
pure
(Type
{ extract = liftA2 (liftA2 (:*:)) extractL extractR
, expected = Record (Data.HashMap.Strict.InsOrd.union ktsL ktsR)
, expected = Record (Dhall.Map.union ktsL ktsR)
}
)

@@ -975,11 +975,11 @@ instance (Selector s, Interpret a) => GenericInterpret (M1 S s (K1 i a)) where
name <- getSelName n
let extract (RecordLit m) = do
let name' = fieldModifier (Data.Text.pack name)
e <- Data.HashMap.Strict.InsOrd.lookup name' m
e <- Dhall.Map.lookup name' m
fmap (M1 . K1) (extract' e)
extract _ = Nothing
let expected =
Record (Data.HashMap.Strict.InsOrd.fromList [(key, expected')])
Record (Dhall.Map.fromList [(key, expected')])
where
key = fieldModifier (Data.Text.pack name)
pure (Type {..})
@@ -1117,9 +1117,9 @@ instance Inject Double where
instance Inject () where
injectWith _ = InputType {..}
where
embed = const (RecordLit Data.HashMap.Strict.InsOrd.empty)
embed = const (RecordLit mempty)

declared = Record Data.HashMap.Strict.InsOrd.empty
declared = Record mempty

instance Inject a => Inject (Maybe a) where
injectWith options = InputType embedOut declaredOut
@@ -1173,13 +1173,13 @@ instance (Constructor c1, Constructor c2, GenericInject f1, GenericInject f2) =>
genericInjectWith options@(InterpretOptions {..}) = pure (InputType {..})
where
embed (L1 (M1 l)) =
UnionLit keyL (embedL l) (Data.HashMap.Strict.InsOrd.singleton keyR declaredR)
UnionLit keyL (embedL l) (Dhall.Map.singleton keyR declaredR)

embed (R1 (M1 r)) =
UnionLit keyR (embedR r) (Data.HashMap.Strict.InsOrd.singleton keyL declaredL)
UnionLit keyR (embedR r) (Dhall.Map.singleton keyL declaredL)

declared =
Union (Data.HashMap.Strict.InsOrd.fromList [(keyL, declaredL), (keyR, declaredR)])
Union (Dhall.Map.fromList [(keyL, declaredL), (keyR, declaredR)])

nL :: M1 i c1 f1 a
nL = undefined
@@ -1197,7 +1197,7 @@ instance (Constructor c, GenericInject (f :+: g), GenericInject h) => GenericInj
genericInjectWith options@(InterpretOptions {..}) = pure (InputType {..})
where
embed (L1 l) =
UnionLit keyL valL (Data.HashMap.Strict.InsOrd.insert keyR declaredR ktsL')
UnionLit keyL valL (Dhall.Map.insert keyR declaredR ktsL')
where
UnionLit keyL valL ktsL' = embedL l
embed (R1 (M1 r)) = UnionLit keyR (embedR r) ktsL
@@ -1207,7 +1207,7 @@ instance (Constructor c, GenericInject (f :+: g), GenericInject h) => GenericInj

keyR = constructorModifier (Data.Text.pack (conName nR))

declared = Union (Data.HashMap.Strict.InsOrd.insert keyR declaredR ktsL)
declared = Union (Dhall.Map.insert keyR declaredR ktsL)

InputType embedL (Union ktsL) = evalState (genericInjectWith options) 1
InputType embedR declaredR = evalState (genericInjectWith options) 1
@@ -1217,7 +1217,7 @@ instance (Constructor c, GenericInject f, GenericInject (g :+: h)) => GenericInj
where
embed (L1 (M1 l)) = UnionLit keyL (embedL l) ktsR
embed (R1 r) =
UnionLit keyR valR (Data.HashMap.Strict.InsOrd.insert keyL declaredL ktsR')
UnionLit keyR valR (Dhall.Map.insert keyL declaredL ktsR')
where
UnionLit keyR valR ktsR' = embedR r

@@ -1226,7 +1226,7 @@ instance (Constructor c, GenericInject f, GenericInject (g :+: h)) => GenericInj

keyL = constructorModifier (Data.Text.pack (conName nL))

declared = Union (Data.HashMap.Strict.InsOrd.insert keyL declaredL ktsR)
declared = Union (Dhall.Map.insert keyL declaredL ktsR)

InputType embedL declaredL = evalState (genericInjectWith options) 1
InputType embedR (Union ktsR) = evalState (genericInjectWith options) 1
@@ -1235,15 +1235,15 @@ instance (GenericInject (f :+: g), GenericInject (h :+: i)) => GenericInject ((f
genericInjectWith options = pure (InputType {..})
where
embed (L1 l) =
UnionLit keyL valR (Data.HashMap.Strict.InsOrd.union ktsL' ktsR)
UnionLit keyL valR (Dhall.Map.union ktsL' ktsR)
where
UnionLit keyL valR ktsL' = embedL l
embed (R1 r) =
UnionLit keyR valR (Data.HashMap.Strict.InsOrd.union ktsL ktsR')
UnionLit keyR valR (Dhall.Map.union ktsL ktsR')
where
UnionLit keyR valR ktsR' = embedR r

declared = Union (Data.HashMap.Strict.InsOrd.union ktsL ktsR)
declared = Union (Dhall.Map.union ktsL ktsR)

InputType embedL (Union ktsL) = evalState (genericInjectWith options) 1
InputType embedR (Union ktsR) = evalState (genericInjectWith options) 1
@@ -1254,12 +1254,12 @@ instance (GenericInject f, GenericInject g) => GenericInject (f :*: g) where
InputType embedInR declaredInR <- genericInjectWith options

let embed (l :*: r) =
RecordLit (Data.HashMap.Strict.InsOrd.union mapL mapR)
RecordLit (Dhall.Map.union mapL mapR)
where
RecordLit mapL = embedInL l
RecordLit mapR = embedInR r

let declared = Record (Data.HashMap.Strict.InsOrd.union mapL mapR)
let declared = Record (Dhall.Map.union mapL mapR)
where
Record mapL = declaredInL
Record mapR = declaredInR
@@ -1269,17 +1269,17 @@ instance (GenericInject f, GenericInject g) => GenericInject (f :*: g) where
instance GenericInject U1 where
genericInjectWith _ = pure (InputType {..})
where
embed _ = RecordLit Data.HashMap.Strict.InsOrd.empty
embed _ = RecordLit mempty

declared = Record Data.HashMap.Strict.InsOrd.empty
declared = Record mempty

instance (Selector s, Inject a) => GenericInject (M1 S s (K1 i a)) where
genericInjectWith opts@(InterpretOptions {..}) = do
name <- fieldModifier . Data.Text.pack <$> getSelName n
let embed (M1 (K1 x)) =
RecordLit (Data.HashMap.Strict.InsOrd.singleton name (embedIn x))
RecordLit (Dhall.Map.singleton name (embedIn x))
let declared =
Record (Data.HashMap.Strict.InsOrd.singleton name declaredIn)
Record (Dhall.Map.singleton name declaredIn)
pure (InputType {..})
where
n :: M1 i s f a
@@ -1327,7 +1327,7 @@ newtype RecordType a =
RecordType
( Data.Functor.Product.Product
( Control.Applicative.Const
( Data.HashMap.Strict.InsOrd.InsOrdHashMap
( Dhall.Map.Map
Text
( Expr Src X )
)
@@ -1360,22 +1360,22 @@ field key valueType =
RecordLit fields <-
return expr

Data.HashMap.Strict.InsOrd.lookup key fields
Dhall.Map.lookup key fields
>>= extract valueType

in
RecordType
( Data.Functor.Product.Pair
( Control.Applicative.Const
( Data.HashMap.Strict.InsOrd.singleton
( Dhall.Map.singleton
key
( Dhall.expected valueType )
)
)
( Data.Functor.Compose.Compose extractBody )
)

{-| The 'RecordInputType' divisible (contravariant) functor allows you to build
{-| The 'RecordInputType' divisible (contravariant) functor allows you to build
an 'InputType' injector for a Dhall record.
For example, let's take the following Haskell data type:
@@ -1432,21 +1432,21 @@ field key valueType =
infixr 5 >*<

newtype RecordInputType a
= RecordInputType (Data.HashMap.Strict.InsOrd.InsOrdHashMap Text (InputType a))
= RecordInputType (Dhall.Map.Map Text (InputType a))

instance Contravariant RecordInputType where
contramap f (RecordInputType inputTypeRecord) = RecordInputType $ contramap f <$> inputTypeRecord

instance Divisible RecordInputType where
divide f (RecordInputType bInputTypeRecord) (RecordInputType cInputTypeRecord) =
RecordInputType
$ Data.HashMap.Strict.InsOrd.union
$ Dhall.Map.union
((contramap $ fst . f) <$> bInputTypeRecord)
((contramap $ snd . f) <$> cInputTypeRecord)
conquer = RecordInputType Data.HashMap.Strict.InsOrd.empty
conquer = RecordInputType mempty

inputFieldWith :: Text -> InputType a -> RecordInputType a
inputFieldWith name inputType = RecordInputType $ Data.HashMap.Strict.InsOrd.singleton name inputType
inputFieldWith name inputType = RecordInputType $ Dhall.Map.singleton name inputType

inputField :: Inject a => Text -> RecordInputType a
inputField name = inputFieldWith name inject
18 changes: 9 additions & 9 deletions src/Dhall/Binary.hs
Original file line number Diff line number Diff line change
@@ -44,11 +44,11 @@ import Options.Applicative (Parser)
import Prelude hiding (exponent)

import qualified Data.Foldable
import qualified Data.HashMap.Strict.InsOrd
import qualified Data.Scientific
import qualified Data.Sequence
import qualified Data.Set
import qualified Data.Text
import qualified Dhall.Map
import qualified Options.Applicative

-- | Supported protocol version strings
@@ -277,15 +277,15 @@ encode_1_1 (Record xTs₀) =
TList [ TInt 7, TMap xTs₁ ]
where
xTs₁ = do
(x₀, _T₀) <- Data.HashMap.Strict.InsOrd.toList xTs₀
(x₀, _T₀) <- Dhall.Map.toList xTs₀
let x₁ = TString x₀
let _T₁ = encode_1_1 _T₀
return (x₁, _T₁)
encode_1_1 (RecordLit xts₀) =
TList [ TInt 8, TMap xts₁ ]
where
xts₁ = do
(x₀, t₀) <- Data.HashMap.Strict.InsOrd.toList xts₀
(x₀, t₀) <- Dhall.Map.toList xts₀
let x₁ = TString x₀
let t₁ = encode_1_1 t₀
return (x₁, t₁)
@@ -302,7 +302,7 @@ encode_1_1 (Union xTs₀) =
TList [ TInt 11, TMap xTs₁ ]
where
xTs₁ = do
(x₀, _T₀) <- Data.HashMap.Strict.InsOrd.toList xTs₀
(x₀, _T₀) <- Dhall.Map.toList xTs₀
let x₁ = TString x₀
let _T₁ = encode_1_1 _T₀
return (x₁, _T₁)
@@ -312,7 +312,7 @@ encode_1_1 (UnionLit x t₀ yTs₀) =
t₁ = encode_1_1 t₀

yTs₁ = do
(y₀, _T₀) <- Data.HashMap.Strict.InsOrd.toList yTs₀
(y₀, _T₀) <- Dhall.Map.toList yTs₀
let y₁ = TString y₀
let _T₁ = encode_1_1 _T₀
return (y₁, _T₁)
@@ -559,7 +559,7 @@ decode_1_1 (TList [ TInt 7, TMap xTs₁ ]) = do

xTs₀ <- traverse process xTs₁

return (Record (Data.HashMap.Strict.InsOrd.fromList xTs₀))
return (Record (Dhall.Map.fromList xTs₀))
decode_1_1 (TList [ TInt 8, TMap xts₁ ]) = do
let process (TString x, t₁) = do
t₀ <- decode_1_1 t₁
@@ -570,7 +570,7 @@ decode_1_1 (TList [ TInt 8, TMap xts₁ ]) = do

xts₀ <- traverse process xts₁

return (RecordLit (Data.HashMap.Strict.InsOrd.fromList xts₀))
return (RecordLit (Dhall.Map.fromList xts₀))
decode_1_1 (TList [ TInt 9, t₁, TString x ]) = do
t₀ <- decode_1_1 t₁

@@ -594,7 +594,7 @@ decode_1_1 (TList [ TInt 11, TMap xTs₁ ]) = do

xTs₀ <- traverse process xTs₁

return (Union (Data.HashMap.Strict.InsOrd.fromList xTs₀))
return (Union (Dhall.Map.fromList xTs₀))
decode_1_1 (TList [ TInt 12, TString x, t₁, TMap yTs₁ ]) = do
t₀ <- decode_1_1 t₁

@@ -607,7 +607,7 @@ decode_1_1 (TList [ TInt 12, TString x, t₁, TMap yTs₁ ]) = do

yTs₀ <- traverse process yTs₁

return (UnionLit x t₀ (Data.HashMap.Strict.InsOrd.fromList yTs₀))
return (UnionLit x t₀ (Dhall.Map.fromList yTs₀))
decode_1_1 (TList [ TInt 13, u₁ ]) = do
u₀ <- decode_1_1 u₁

163 changes: 113 additions & 50 deletions src/Dhall/Core.hs
Original file line number Diff line number Diff line change
@@ -64,8 +64,6 @@ import Crypto.Hash (SHA256)
import Data.Bifunctor (Bifunctor(..))
import Data.Data (Data)
import Data.Foldable
import Data.Hashable (Hashable)
import Data.HashMap.Strict.InsOrd (InsOrdHashMap)
import Data.HashSet (HashSet)
import Data.String (IsString(..))
import Data.Scientific (Scientific)
@@ -75,21 +73,20 @@ import Data.Set (Set)
import Data.Text (Text)
import Data.Text.Prettyprint.Doc (Pretty)
import Data.Traversable
import Dhall.Map (Map)
import {-# SOURCE #-} Dhall.Pretty.Internal
import GHC.Generics (Generic)
import Numeric.Natural (Natural)
import Prelude hiding (succ)

import qualified Control.Monad
import qualified Crypto.Hash
import qualified Data.List
import qualified Data.HashMap.Strict.InsOrd
import qualified Data.HashSet
import qualified Data.Ord
import qualified Data.Sequence
import qualified Data.Set
import qualified Data.Text
import qualified Data.Text.Prettyprint.Doc as Pretty
import qualified Dhall.Map

{-| Constants for a pure type system
@@ -424,13 +421,13 @@ data Expr s a
-- | > OptionalBuild ~ Optional/build
| OptionalBuild
-- | > Record [(k1, t1), (k2, t2)] ~ { k1 : t1, k2 : t1 }
| Record (InsOrdHashMap Text (Expr s a))
| Record (Map Text (Expr s a))
-- | > RecordLit [(k1, v1), (k2, v2)] ~ { k1 = v1, k2 = v2 }
| RecordLit (InsOrdHashMap Text (Expr s a))
| RecordLit (Map Text (Expr s a))
-- | > Union [(k1, t1), (k2, t2)] ~ < k1 : t1 | k2 : t2 >
| Union (InsOrdHashMap Text (Expr s a))
| Union (Map Text (Expr s a))
-- | > UnionLit k v [(k1, t1), (k2, t2)] ~ < k = v | k1 : t1 | k2 : t2 >
| UnionLit Text (Expr s a) (InsOrdHashMap Text (Expr s a))
| UnionLit Text (Expr s a) (Map Text (Expr s a))
-- | > Combine x y ~ x ∧ y
| Combine (Expr s a) (Expr s a)
-- | > CombineTypes x y ~ x ⩓ y
@@ -452,7 +449,79 @@ data Expr s a
| ImportAlt (Expr s a) (Expr s a)
-- | > Embed import ~ import
| Embed a
deriving (Functor, Foldable, Generic, Traversable, Show, Eq, Data)
deriving (Eq, Foldable, Generic, Traversable, Show, Data)

-- This instance is hand-written due to the fact that deriving
-- it does not give us an INLINABLE pragma. We annotate this fmap
-- implementation with this pragma below to allow GHC to, possibly,
-- inline the implementation for performance improvements.
instance Functor (Expr s) where
fmap _ (Const c) = Const c
fmap _ (Var v) = Var v
fmap f (Lam v e1 e2) = Lam v (fmap f e1) (fmap f e2)
fmap f (Pi v e1 e2) = Pi v (fmap f e1) (fmap f e2)
fmap f (App e1 e2) = App (fmap f e1) (fmap f e2)
fmap f (Let v maybeE e1 e2) = Let v (fmap (fmap f) maybeE) (fmap f e1) (fmap f e2)
fmap f (Annot e1 e2) = Annot (fmap f e1) (fmap f e2)
fmap _ Bool = Bool
fmap _ (BoolLit b) = BoolLit b
fmap f (BoolAnd e1 e2) = BoolAnd (fmap f e1) (fmap f e2)
fmap f (BoolOr e1 e2) = BoolOr (fmap f e1) (fmap f e2)
fmap f (BoolEQ e1 e2) = BoolEQ (fmap f e1) (fmap f e2)
fmap f (BoolNE e1 e2) = BoolNE (fmap f e1) (fmap f e2)
fmap f (BoolIf e1 e2 e3) = BoolIf (fmap f e1) (fmap f e2) (fmap f e3)
fmap _ Natural = Natural
fmap _ (NaturalLit n) = NaturalLit n
fmap _ NaturalFold = NaturalFold
fmap _ NaturalBuild = NaturalBuild
fmap _ NaturalIsZero = NaturalIsZero
fmap _ NaturalEven = NaturalEven
fmap _ NaturalOdd = NaturalOdd
fmap _ NaturalToInteger = NaturalToInteger
fmap _ NaturalShow = NaturalShow
fmap f (NaturalPlus e1 e2) = NaturalPlus (fmap f e1) (fmap f e2)
fmap f (NaturalTimes e1 e2) = NaturalTimes (fmap f e1) (fmap f e2)
fmap _ Integer = Integer
fmap _ (IntegerLit i) = IntegerLit i
fmap _ IntegerShow = IntegerShow
fmap _ IntegerToDouble = IntegerToDouble
fmap _ Double = Double
fmap _ (DoubleLit d) = DoubleLit d
fmap _ DoubleShow = DoubleShow
fmap _ Text = Text
fmap f (TextLit cs) = TextLit (fmap f cs)
fmap f (TextAppend e1 e2) = TextAppend (fmap f e1) (fmap f e2)
fmap _ List = List
fmap f (ListLit maybeE seqE) = ListLit (fmap (fmap f) maybeE) (fmap (fmap f) seqE)
fmap f (ListAppend e1 e2) = ListAppend (fmap f e1) (fmap f e2)
fmap _ ListBuild = ListBuild
fmap _ ListFold = ListFold
fmap _ ListLength = ListLength
fmap _ ListHead = ListHead
fmap _ ListLast = ListLast
fmap _ ListIndexed = ListIndexed
fmap _ ListReverse = ListReverse
fmap _ Optional = Optional
fmap f (OptionalLit e maybeE) = OptionalLit (fmap f e) (fmap (fmap f) maybeE)
fmap f (Some e) = Some (fmap f e)
fmap _ None = None
fmap _ OptionalFold = OptionalFold
fmap _ OptionalBuild = OptionalBuild
fmap f (Record r) = Record (fmap (fmap f) r)
fmap f (RecordLit r) = RecordLit (fmap (fmap f) r)
fmap f (Union u) = Union (fmap (fmap f) u)
fmap f (UnionLit v e u) = UnionLit v (fmap f e) (fmap (fmap f) u)
fmap f (Combine e1 e2) = Combine (fmap f e1) (fmap f e2)
fmap f (CombineTypes e1 e2) = CombineTypes (fmap f e1) (fmap f e2)
fmap f (Prefer e1 e2) = Prefer (fmap f e1) (fmap f e2)
fmap f (Merge e1 e2 maybeE) = Merge (fmap f e1) (fmap f e2) (fmap (fmap f) maybeE)
fmap f (Constructors e1) = Constructors (fmap f e1)
fmap f (Field e1 v) = Field (fmap f e1) v
fmap f (Project e1 vs) = Project (fmap f e1) vs
fmap f (Note s e1) = Note s (fmap f e1)
fmap f (ImportAlt e1 e2) = ImportAlt (fmap f e1) (fmap f e2)
fmap f (Embed a) = Embed (f a)
{-# INLINABLE fmap #-}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's worth adding a comment noting that this annotation is the whole reason why this instance isn't derived.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


instance Applicative (Expr s) where
pure = Embed
@@ -1403,12 +1472,6 @@ denote (Project a b ) = Project (denote a) b
denote (ImportAlt a b ) = ImportAlt (denote a) (denote b)
denote (Embed a ) = Embed a

sortMap :: (Ord k, Hashable k) => InsOrdHashMap k v -> InsOrdHashMap k v
sortMap =
Data.HashMap.Strict.InsOrd.fromList
. Data.List.sortBy (Data.Ord.comparing fst)
. Data.HashMap.Strict.InsOrd.toList

{-| Reduce an expression to its normal form, performing beta reduction and applying
any custom definitions.
@@ -1531,7 +1594,7 @@ normalizeWith ctx e0 = loop (denote e0)
where
as₁ = Data.Sequence.mapWithIndex adapt as₀

_A₂ = Record (Data.HashMap.Strict.InsOrd.fromList kts)
_A₂ = Record (Dhall.Map.fromList kts)
where
kts = [ ("index", Natural)
, ("value", _A₀)
@@ -1541,7 +1604,7 @@ normalizeWith ctx e0 = loop (denote e0)
| otherwise = Nothing

adapt n a_ =
RecordLit (Data.HashMap.Strict.InsOrd.fromList kvs)
RecordLit (Dhall.Map.fromList kvs)
where
kvs = [ ("index", NaturalLit (fromIntegral n))
, ("value", a_)
@@ -1684,56 +1747,56 @@ normalizeWith ctx e0 = loop (denote e0)
None -> None
OptionalFold -> OptionalFold
OptionalBuild -> OptionalBuild
Record kts -> Record (sortMap kts')
Record kts -> Record (Dhall.Map.sort kts')
where
kts' = fmap loop kts
RecordLit kvs -> RecordLit (sortMap kvs')
RecordLit kvs -> RecordLit (Dhall.Map.sort kvs')
where
kvs' = fmap loop kvs
Union kts -> Union (sortMap kts')
Union kts -> Union (Dhall.Map.sort kts')
where
kts' = fmap loop kts
UnionLit k v kvs -> UnionLit k v' (sortMap kvs')
UnionLit k v kvs -> UnionLit k v' (Dhall.Map.sort kvs')
where
v' = loop v
kvs' = fmap loop kvs
Combine x y -> decide (loop x) (loop y)
where
decide (RecordLit m) r | Data.HashMap.Strict.InsOrd.null m =
decide (RecordLit m) r | Data.Foldable.null m =
r
decide l (RecordLit n) | Data.HashMap.Strict.InsOrd.null n =
decide l (RecordLit n) | Data.Foldable.null n =
l
decide (RecordLit m) (RecordLit n) =
RecordLit (sortMap (Data.HashMap.Strict.InsOrd.unionWith decide m n))
RecordLit (Dhall.Map.sort (Dhall.Map.unionWith decide m n))
decide l r =
Combine l r
CombineTypes x y -> decide (loop x) (loop y)
where
decide (Record m) r | Data.HashMap.Strict.InsOrd.null m =
decide (Record m) r | Data.Foldable.null m =
r
decide l (Record n) | Data.HashMap.Strict.InsOrd.null n =
decide l (Record n) | Data.Foldable.null n =
l
decide (Record m) (Record n) =
Record (sortMap (Data.HashMap.Strict.InsOrd.unionWith decide m n))
Record (Dhall.Map.sort (Dhall.Map.unionWith decide m n))
decide l r =
CombineTypes l r

Prefer x y -> decide (loop x) (loop y)
where
decide (RecordLit m) r | Data.HashMap.Strict.InsOrd.null m =
decide (RecordLit m) r | Data.Foldable.null m =
r
decide l (RecordLit n) | Data.HashMap.Strict.InsOrd.null n =
decide l (RecordLit n) | Data.Foldable.null n =
l
decide (RecordLit m) (RecordLit n) =
RecordLit (sortMap (Data.HashMap.Strict.InsOrd.union n m))
RecordLit (Dhall.Map.sort (Dhall.Map.union n m))
decide l r =
Prefer l r
Merge x y t ->
case x' of
RecordLit kvsX ->
case y' of
UnionLit kY vY _ ->
case Data.HashMap.Strict.InsOrd.lookup kY kvsX of
case Dhall.Map.lookup kY kvsX of
Just vX -> loop (App vX vY)
Nothing -> Merge x' y' t'
_ -> Merge x' y' t'
@@ -1746,18 +1809,18 @@ normalizeWith ctx e0 = loop (denote e0)
case t' of
Union kts -> RecordLit kvs
where
kvs = Data.HashMap.Strict.InsOrd.mapWithKey adapt kts
kvs = Dhall.Map.mapWithKey adapt kts

adapt k t_ = Lam k t_ (UnionLit k (Var (V k 0)) rest)
where
rest = Data.HashMap.Strict.InsOrd.delete k kts
rest = Dhall.Map.delete k kts
_ -> Constructors t'
where
t' = loop t
Field r x ->
case loop r of
RecordLit kvs ->
case Data.HashMap.Strict.InsOrd.lookup x kvs of
case Dhall.Map.lookup x kvs of
Just v -> loop v
Nothing -> Field (RecordLit (fmap loop kvs)) x
r' -> Field r' x
@@ -1768,12 +1831,12 @@ normalizeWith ctx e0 = loop (denote e0)
Just s ->
loop (RecordLit kvs')
where
kvs' = Data.HashMap.Strict.InsOrd.fromList s
kvs' = Dhall.Map.fromList s
Nothing ->
Project (RecordLit (fmap loop kvs)) xs
where
adapt x = do
v <- Data.HashMap.Strict.InsOrd.lookup x kvs
v <- Dhall.Map.lookup x kvs
return (x, v)
r' -> Project r' xs
Note _ e' -> loop e'
@@ -1948,34 +2011,34 @@ isNormalized e0 = loop (denote e0)
None -> True
OptionalFold -> True
OptionalBuild -> True
Record kts -> all loop kts
RecordLit kvs -> all loop kvs
Union kts -> all loop kts
UnionLit _ v kvs -> loop v && all loop kvs
Record kts -> Dhall.Map.isSorted kts && all loop kts
RecordLit kvs -> Dhall.Map.isSorted kvs && all loop kvs
Union kts -> Dhall.Map.isSorted kts && all loop kts
UnionLit _ v kvs -> loop v && Dhall.Map.isSorted kvs && all loop kvs
Combine x y -> loop x && loop y && decide x y
where
decide (RecordLit m) _ | Data.HashMap.Strict.InsOrd.null m = False
decide _ (RecordLit n) | Data.HashMap.Strict.InsOrd.null n = False
decide (RecordLit m) _ | Data.Foldable.null m = False
decide _ (RecordLit n) | Data.Foldable.null n = False
decide (RecordLit _) (RecordLit _) = False
decide _ _ = True
CombineTypes x y -> loop x && loop y && decide x y
where
decide (Record m) _ | Data.HashMap.Strict.InsOrd.null m = False
decide _ (Record n) | Data.HashMap.Strict.InsOrd.null n = False
decide (Record m) _ | Data.Foldable.null m = False
decide _ (Record n) | Data.Foldable.null n = False
decide (Record _) (Record _) = False
decide _ _ = True
Prefer x y -> loop x && loop y && decide x y
where
decide (RecordLit m) _ | Data.HashMap.Strict.InsOrd.null m = False
decide _ (RecordLit n) | Data.HashMap.Strict.InsOrd.null n = False
decide (RecordLit m) _ | Data.Foldable.null m = False
decide _ (RecordLit n) | Data.Foldable.null n = False
decide (RecordLit _) (RecordLit _) = False
decide _ _ = True
Merge x y t -> loop x && loop y && all loop t &&
case x of
RecordLit kvsX ->
case y of
UnionLit kY _ _ ->
case Data.HashMap.Strict.InsOrd.lookup kY kvsX of
case Dhall.Map.lookup kY kvsX of
Just _ -> False
Nothing -> True
_ -> True
@@ -1988,14 +2051,14 @@ isNormalized e0 = loop (denote e0)
Field r x -> loop r &&
case r of
RecordLit kvs ->
case Data.HashMap.Strict.InsOrd.lookup x kvs of
case Dhall.Map.lookup x kvs of
Just _ -> False
Nothing -> True
_ -> True
Project r xs -> loop r &&
case r of
RecordLit kvs ->
if all (flip Data.HashMap.Strict.InsOrd.member kvs) xs
if all (flip Dhall.Map.member kvs) xs
then False
else True
_ -> True
26 changes: 13 additions & 13 deletions src/Dhall/Diff.hs
Original file line number Diff line number Diff line change
@@ -17,7 +17,6 @@ module Dhall.Diff (

import Data.Foldable (fold, toList)
import Data.Function (on)
import Data.HashMap.Strict.InsOrd (InsOrdHashMap)
import Data.List.NonEmpty (NonEmpty(..))
import Data.Monoid (Any(..))
import Data.Scientific (Scientific)
@@ -28,16 +27,17 @@ import Data.String (IsString(..))
import Data.Text (Text)
import Data.Text.Prettyprint.Doc (Doc, Pretty)
import Dhall.Core (Chunks (..), Const(..), Expr(..), Var(..))
import Dhall.Map (Map)
import Dhall.Pretty.Internal (Ann)
import Numeric.Natural (Natural)

import qualified Data.Algorithm.Diff as Algo.Diff
import qualified Data.HashMap.Strict.InsOrd as HashMap
import qualified Data.List.NonEmpty
import qualified Data.Set
import qualified Data.Text
import qualified Data.Text.Prettyprint.Doc as Pretty
import qualified Dhall.Core
import qualified Dhall.Map
import qualified Dhall.Pretty.Internal as Internal

data Diff =
@@ -248,14 +248,14 @@ enclosed' l m docs =
diffKeyVals
:: (Eq a, Pretty a)
=> Diff
-> InsOrdHashMap Text (Expr s a)
-> InsOrdHashMap Text (Expr s a)
-> Map Text (Expr s a)
-> Map Text (Expr s a)
-> [Diff]
diffKeyVals assign kvsL kvsR =
diffFieldNames <> diffFieldValues <> (if anyEqual then [ ignore ] else [])
where
ksL = Data.Set.fromList (HashMap.keys kvsL)
ksR = Data.Set.fromList (HashMap.keys kvsR)
ksL = Data.Set.fromList (Dhall.Map.keys kvsL)
ksR = Data.Set.fromList (Dhall.Map.keys kvsR)

extraL = Data.Set.difference ksL ksR
extraR = Data.Set.difference ksR ksL
@@ -270,10 +270,10 @@ diffKeyVals assign kvsL kvsR =
<> ignore
]

shared = HashMap.intersectionWith diffExpression kvsL kvsR
shared = Dhall.Map.intersectionWith diffExpression kvsL kvsR

diffFieldValues =
filter (not . same) (HashMap.foldMapWithKey adapt shared)
filter (not . same) (Dhall.Map.foldMapWithKey adapt shared)
where
adapt key doc =
[ (if ksL == ksR then mempty else " ")
@@ -391,17 +391,17 @@ isBoth p

diffRecord
:: (Eq a, Pretty a)
=> InsOrdHashMap Text (Expr s a) -> InsOrdHashMap Text (Expr s a) -> Diff
=> Map Text (Expr s a) -> Map Text (Expr s a) -> Diff
diffRecord kvsL kvsR = braced (diffKeyVals colon kvsL kvsR)

diffRecordLit
:: (Eq a, Pretty a)
=> InsOrdHashMap Text (Expr s a) -> InsOrdHashMap Text (Expr s a) -> Diff
=> Map Text (Expr s a) -> Map Text (Expr s a) -> Diff
diffRecordLit kvsL kvsR = braced (diffKeyVals equals kvsL kvsR)

diffUnion
:: (Eq a, Pretty a)
=> InsOrdHashMap Text (Expr s a) -> InsOrdHashMap Text (Expr s a) -> Diff
=> Map Text (Expr s a) -> Map Text (Expr s a) -> Diff
diffUnion kvsL kvsR = angled (diffKeyVals colon kvsL kvsR)

diffUnionLit
@@ -410,8 +410,8 @@ diffUnionLit
-> Text
-> Expr s a
-> Expr s a
-> InsOrdHashMap Text (Expr s a)
-> InsOrdHashMap Text (Expr s a)
-> Map Text (Expr s a)
-> Map Text (Expr s a)
-> Diff
diffUnionLit kL kR vL vR kvsL kvsR =
langle
2 changes: 1 addition & 1 deletion src/Dhall/Freeze.hs
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@ import Data.Maybe (fromMaybe)
import Data.Text
import Dhall.Binary (ProtocolVersion(..))
import Dhall.Core (Expr(..), Import(..), ImportHashed(..))
import Dhall.Import (hashExpression, protocolVersion)
import Dhall.Import (protocolVersion)
import Dhall.Parser (exprAndHeaderFromText, Src)
import Dhall.Pretty (annToAnsiStyle, layoutOpts)
import Lens.Family (set)
8 changes: 4 additions & 4 deletions src/Dhall/Import.hs
Original file line number Diff line number Diff line change
@@ -177,14 +177,14 @@ import qualified Data.ByteString
import qualified Data.ByteString.Lazy
import qualified Data.CaseInsensitive
import qualified Data.Foldable
import qualified Data.HashMap.Strict.InsOrd
import qualified Data.List.NonEmpty as NonEmpty
import qualified Data.Map.Strict as Map
import qualified Data.Text.Encoding
import qualified Data.Text as Text
import qualified Data.Text.IO
import qualified Dhall.Binary
import qualified Dhall.Core
import qualified Dhall.Map
import qualified Dhall.Parser
import qualified Dhall.Pretty.Internal
import qualified Dhall.TypeCheck
@@ -409,8 +409,8 @@ toHeader
:: Expr s a
-> Maybe (CI Data.ByteString.ByteString, Data.ByteString.ByteString)
toHeader (RecordLit m) = do
TextLit (Chunks [] keyText ) <- Data.HashMap.Strict.InsOrd.lookup "header" m
TextLit (Chunks [] valueText) <- Data.HashMap.Strict.InsOrd.lookup "value" m
TextLit (Chunks [] keyText ) <- Dhall.Map.lookup "header" m
TextLit (Chunks [] valueText) <- Dhall.Map.lookup "value" m
let keyBytes = Data.Text.Encoding.encodeUtf8 keyText
let valueBytes = Data.Text.Encoding.encodeUtf8 valueText
return (Data.CaseInsensitive.mk keyBytes, valueBytes)
@@ -631,7 +631,7 @@ exprFromUncachedImport (Import {..}) = do
expected =
App List
( Record
( Data.HashMap.Strict.InsOrd.fromList
( Dhall.Map.fromList
[("header", Text), ("value", Text)]
)
)
481 changes: 481 additions & 0 deletions src/Dhall/Map.hs

Large diffs are not rendered by default.

17 changes: 7 additions & 10 deletions src/Dhall/Parser/Combinators.hs
Original file line number Diff line number Diff line change
@@ -8,26 +8,25 @@ module Dhall.Parser.Combinators where
import Control.Applicative (Alternative (..), liftA2)
import Control.Monad (MonadPlus (..))
import Data.Data (Data)
import Data.HashMap.Strict.InsOrd (InsOrdHashMap)
import Data.Semigroup (Semigroup (..))
import Data.Sequence (ViewL (..))
import Data.Set (Set)
import Data.String (IsString (..))
import Data.Text (Text)
import Data.Text.Prettyprint.Doc (Pretty (..))
import Data.Void (Void)
import Dhall.Map (Map)
import Prelude hiding (const, pi)
import Text.Parser.Combinators (try, (<?>))
import Text.Parser.Token (TokenParsing (..))

import qualified Control.Monad.Fail
import qualified Data.Char
import qualified Data.HashMap.Strict.InsOrd
import qualified Data.List
import qualified Data.Sequence
import qualified Data.Set
import qualified Data.Text
import qualified Dhall.Map
import qualified Dhall.Util
import qualified Control.Monad.Fail
import qualified Text.Megaparsec
import qualified Text.Megaparsec.Char
import qualified Text.Parser.Char
@@ -246,7 +245,7 @@ noDuplicates = go Data.Set.empty
then fail "Duplicate key"
else go (Data.Set.insert x found) xs

toMap :: [(Text, a)] -> Parser (InsOrdHashMap Text a)
toMap :: [(Text, a)] -> Parser (Map Text a)
toMap kvs = do
let adapt (k, v) = (k, pure v)
let m = fromListWith (<|>) (fmap adapt kvs)
@@ -258,10 +257,8 @@ toMap kvs = do
else
Text.Parser.Combinators.unexpected
("duplicate field: " ++ Data.Text.unpack k)
Data.HashMap.Strict.InsOrd.traverseWithKey action m
Dhall.Map.traverseWithKey action m
where
fromListWith combine = Data.List.foldl' snoc nil
fromListWith combine = foldr cons mempty
where
nil = Data.HashMap.Strict.InsOrd.empty

snoc m (k, v) = Data.HashMap.Strict.InsOrd.insertWith combine k v m
cons (k, v) = Dhall.Map.insertWith combine k v
7 changes: 3 additions & 4 deletions src/Dhall/Parser/Expression.hs
Original file line number Diff line number Diff line change
@@ -20,7 +20,6 @@ import qualified Crypto.Hash
import qualified Data.ByteArray.Encoding
import qualified Data.ByteString
import qualified Data.Char
import qualified Data.HashMap.Strict.InsOrd
import qualified Data.Sequence
import qualified Data.Text
import qualified Data.Text.Encoding
@@ -502,11 +501,11 @@ completeExpression embedded = completeExpression_
where
alternative0 = do
_equal
return (RecordLit Data.HashMap.Strict.InsOrd.empty)
return (RecordLit mempty)

alternative1 = nonEmptyRecordTypeOrLiteral

alternative2 = return (Record Data.HashMap.Strict.InsOrd.empty)
alternative2 = return (Record mempty)

nonEmptyRecordTypeOrLiteral = do
a <- label
@@ -539,7 +538,7 @@ completeExpression embedded = completeExpression_

unionTypeOrLiteral =
nonEmptyUnionTypeOrLiteral
<|> return (Union Data.HashMap.Strict.InsOrd.empty)
<|> return (Union mempty)

nonEmptyUnionTypeOrLiteral = do
(f, kvs) <- loop
22 changes: 11 additions & 11 deletions src/Dhall/Pretty/Internal.hs
Original file line number Diff line number Diff line change
@@ -60,25 +60,25 @@ import {-# SOURCE #-} Dhall.Core
import Control.Applicative (Applicative(..), (<$>))
#endif
import Data.Foldable
import Data.HashMap.Strict.InsOrd (InsOrdHashMap)
import Data.Monoid ((<>))
import Data.Scientific (Scientific)
import Data.Set (Set)
import Data.Text (Text)
import Data.Text.Prettyprint.Doc (Doc, Pretty, space)
import Dhall.Map (Map)
import Numeric.Natural (Natural)
import Prelude hiding (succ)
import qualified Data.Text.Prettyprint.Doc.Render.Terminal as Terminal

import qualified Data.Char
import qualified Data.HashMap.Strict.InsOrd
import qualified Data.HashSet
import qualified Data.List
import qualified Data.Set
import qualified Data.Text as Text
import qualified Data.Text.Prettyprint.Doc as Pretty
import qualified Data.Text.Prettyprint.Doc.Render.Text as Pretty
import qualified Data.Text.Prettyprint.Doc.Render.String as Pretty
import qualified Dhall.Map

{-| Annotation type used to tag elements in a pretty-printed document for
syntax highlighting purposes
@@ -818,25 +818,25 @@ prettyCharacterSet characterSet = prettyExpression
where
long = Pretty.hardline <> " " <> prettyExpression value

prettyRecord :: Pretty a => InsOrdHashMap Text (Expr s a) -> Doc Ann
prettyRecord :: Pretty a => Map Text (Expr s a) -> Doc Ann
prettyRecord =
braces . map (prettyKeyValue colon) . Data.HashMap.Strict.InsOrd.toList
braces . map (prettyKeyValue colon) . Dhall.Map.toList

prettyRecordLit :: Pretty a => InsOrdHashMap Text (Expr s a) -> Doc Ann
prettyRecordLit :: Pretty a => Map Text (Expr s a) -> Doc Ann
prettyRecordLit a
| Data.HashMap.Strict.InsOrd.null a =
| Data.Foldable.null a =
lbrace <> equals <> rbrace
| otherwise
= braces (map (prettyKeyValue equals) (Data.HashMap.Strict.InsOrd.toList a))
= braces (map (prettyKeyValue equals) (Dhall.Map.toList a))

prettyUnion :: Pretty a => InsOrdHashMap Text (Expr s a) -> Doc Ann
prettyUnion :: Pretty a => Map Text (Expr s a) -> Doc Ann
prettyUnion =
angles . map (prettyKeyValue colon) . Data.HashMap.Strict.InsOrd.toList
angles . map (prettyKeyValue colon) . Dhall.Map.toList

prettyUnionLit
:: Pretty a => Text -> Expr s a -> InsOrdHashMap Text (Expr s a) -> Doc Ann
:: Pretty a => Text -> Expr s a -> Map Text (Expr s a) -> Doc Ann
prettyUnionLit a b c =
angles (front : map adapt (Data.HashMap.Strict.InsOrd.toList c))
angles (front : map adapt (Dhall.Map.toList c))
where
front = prettyKeyValue equals (a, b)

77 changes: 35 additions & 42 deletions src/Dhall/TypeCheck.hs
Original file line number Diff line number Diff line change
@@ -24,8 +24,8 @@ module Dhall.TypeCheck (
import Control.Exception (Exception)
import Data.Data (Data(..))
import Data.Foldable (forM_, toList)
import Data.Monoid ((<>))
import Data.Sequence (Seq, ViewL(..))
import Data.Semigroup (Semigroup(..))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is an ambiguous occurrence between the <> coming from here and the one above from Data.Monoid. I'd recommend removing the one from Data.Monoid

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also happens in src/Dhall.hs. This seems to be just for GHC-8.2 btw

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For ghc-7.10.3 too 😉

import Data.Set (Set)
import Data.Text (Text)
import Data.Text.Prettyprint.Doc (Doc, Pretty(..))
@@ -36,8 +36,6 @@ import Dhall.Context (Context)
import Dhall.Pretty (Ann, layoutOpts)

import qualified Data.Foldable
import qualified Data.HashMap.Strict
import qualified Data.HashMap.Strict.InsOrd
import qualified Data.Sequence
import qualified Data.Set
import qualified Data.Text as Text
@@ -46,6 +44,7 @@ import qualified Data.Text.Prettyprint.Doc.Render.String as Pretty
import qualified Dhall.Context
import qualified Dhall.Core
import qualified Dhall.Diff
import qualified Dhall.Map
import qualified Dhall.Pretty.Internal
import qualified Dhall.Util

@@ -425,7 +424,7 @@ typeWithA tpa = loop
return
(Pi "a" (Const Type)
(Pi "_" (App List "a")
(App List (Record (Data.HashMap.Strict.InsOrd.fromList kts))) ) )
(App List (Record (Dhall.Map.fromList kts))) ) )
loop _ ListReverse = do
return (Pi "a" (Const Type) (Pi "_" (App List "a") (App List "a")))
loop _ Optional = do
@@ -468,9 +467,9 @@ typeWithA tpa = loop
(Pi "just" (Pi "_" "a" "optional")
(Pi "nothing" "optional" "optional") )
loop ctx e@(Record kts ) = do
case Data.HashMap.Strict.InsOrd.toList kts of
[] -> return (Const Type)
(k0, t0):rest -> do
case Dhall.Map.uncons kts of
Nothing -> return (Const Type)
Just (k0, t0, rest) -> do
s0 <- fmap Dhall.Core.normalize (loop ctx t0)
c <- case s0 of
Const Type ->
@@ -479,7 +478,7 @@ typeWithA tpa = loop
| Dhall.Core.judgmentallyEqual t0 (Const Type) ->
return Kind
_ -> Left (TypeError ctx e (InvalidFieldType k0 t0))
let process (k, t) = do
let process k t = do
s <- fmap Dhall.Core.normalize (loop ctx t)
case s of
Const Type ->
@@ -495,11 +494,11 @@ typeWithA tpa = loop
else Left (TypeError ctx e (FieldAnnotationMismatch k t k0 t0 Kind))
_ ->
Left (TypeError ctx e (InvalidFieldType k t))
mapM_ process rest
Dhall.Map.traverseWithKey_ process rest
return (Const c)
loop ctx e@(RecordLit kvs ) = do
case Data.HashMap.Strict.InsOrd.toList kvs of
[] -> return (Record Data.HashMap.Strict.InsOrd.empty)
case Dhall.Map.toList kvs of
[] -> return (Record mempty)
(k0, v0):_ -> do
t0 <- loop ctx v0
s0 <- fmap Dhall.Core.normalize (loop ctx t0)
@@ -529,7 +528,7 @@ typeWithA tpa = loop
Left (TypeError ctx e (InvalidField k t))

return t
kts <- Data.HashMap.Strict.InsOrd.traverseWithKey process kvs
kts <- Dhall.Map.traverseWithKey process kvs
return (Record kts)
loop ctx e@(Union kts ) = do
let process k t = do
@@ -538,20 +537,14 @@ typeWithA tpa = loop
Const Type -> return ()
Const Kind -> return ()
_ -> Left (TypeError ctx e (InvalidAlternativeType k t))
-- toList from insert-ordered-containers does some work to
-- ensure that the elements do follow insertion order. In this
-- instance, insertion order doesn't matter: we only need to
-- peek at each element to make sure it is well-typed. If
-- there are multiple type errors, it does not matter which
-- gets reported first here.
Data.HashMap.Strict.foldrWithKey (\ k t prev -> prev >> process k t) (Right ()) (Data.HashMap.Strict.InsOrd.toHashMap kts)
Dhall.Map.traverseWithKey_ process kts
return (Const Type)
loop ctx e@(UnionLit k v kts) = do
case Data.HashMap.Strict.InsOrd.lookup k kts of
case Dhall.Map.lookup k kts of
Just _ -> Left (TypeError ctx e (DuplicateAlternative k))
Nothing -> return ()
t <- loop ctx v
let union = Union (Data.HashMap.Strict.InsOrd.insert k (Dhall.Core.normalize t) kts)
let union = Union (Dhall.Map.insert k (Dhall.Core.normalize t) kts)
_ <- loop ctx union
return union
loop ctx e@(Combine kvsX kvsY) = do
@@ -581,12 +574,12 @@ typeWithA tpa = loop

let combineTypes ktsL ktsR = do
let ksL =
Data.Set.fromList (Data.HashMap.Strict.InsOrd.keys ktsL)
Data.Set.fromList (Dhall.Map.keys ktsL)
let ksR =
Data.Set.fromList (Data.HashMap.Strict.InsOrd.keys ktsR)
Data.Set.fromList (Dhall.Map.keys ktsR)
let ks = Data.Set.union ksL ksR
kts <- forM (toList ks) (\k -> do
case (Data.HashMap.Strict.InsOrd.lookup k ktsL, Data.HashMap.Strict.InsOrd.lookup k ktsR) of
case (Dhall.Map.lookup k ktsL, Dhall.Map.lookup k ktsR) of
(Just (Record ktsL'), Just (Record ktsR')) -> do
t <- combineTypes ktsL' ktsR'
return (k, t)
@@ -596,7 +589,7 @@ typeWithA tpa = loop
return (k, t)
_ -> do
Left (TypeError ctx e (FieldCollision k)) )
return (Record (Data.HashMap.Strict.InsOrd.fromList kts))
return (Record (Dhall.Map.fromList kts))

combineTypes ktsX ktsY
loop ctx e@(CombineTypes l r) = do
@@ -627,12 +620,12 @@ typeWithA tpa = loop

let combineTypes ktsL ktsR = do
let ksL =
Data.Set.fromList (Data.HashMap.Strict.InsOrd.keys ktsL)
Data.Set.fromList (Dhall.Map.keys ktsL)
let ksR =
Data.Set.fromList (Data.HashMap.Strict.InsOrd.keys ktsR)
Data.Set.fromList (Dhall.Map.keys ktsR)
let ks = Data.Set.union ksL ksR
forM_ (toList ks) (\k -> do
case (Data.HashMap.Strict.InsOrd.lookup k ktsL, Data.HashMap.Strict.InsOrd.lookup k ktsR) of
case (Dhall.Map.lookup k ktsL, Dhall.Map.lookup k ktsR) of
(Just (Record ktsL'), Just (Record ktsR')) -> do
combineTypes ktsL' ktsR'
(Nothing, Just _) -> do
@@ -670,21 +663,21 @@ typeWithA tpa = loop
then return ()
else Left (TypeError ctx e (RecordMismatch '' kvsX kvsY constX constY))

return (Record (Data.HashMap.Strict.InsOrd.union ktsY ktsX))
return (Record (Dhall.Map.union ktsY ktsX))
loop ctx e@(Merge kvsX kvsY (Just t)) = do
_ <- loop ctx t

tKvsX <- fmap Dhall.Core.normalize (loop ctx kvsX)
ktsX <- case tKvsX of
Record kts -> return kts
_ -> Left (TypeError ctx e (MustMergeARecord kvsX tKvsX))
let ksX = Data.Set.fromList (Data.HashMap.Strict.InsOrd.keys ktsX)
let ksX = Data.Set.fromList (Dhall.Map.keys ktsX)

tKvsY <- fmap Dhall.Core.normalize (loop ctx kvsY)
ktsY <- case tKvsY of
Union kts -> return kts
_ -> Left (TypeError ctx e (MustMergeUnion kvsY tKvsY))
let ksY = Data.Set.fromList (Data.HashMap.Strict.InsOrd.keys ktsY)
let ksY = Data.Set.fromList (Dhall.Map.keys ktsY)

let diffX = Data.Set.difference ksX ksY
let diffY = Data.Set.difference ksY ksX
@@ -694,7 +687,7 @@ typeWithA tpa = loop
else Left (TypeError ctx e (UnusedHandler diffX))

let process (kY, tY) = do
case Data.HashMap.Strict.InsOrd.lookup kY ktsX of
case Dhall.Map.lookup kY ktsX of
Nothing -> Left (TypeError ctx e (MissingHandler diffY))
Just tX ->
case tX of
@@ -707,20 +700,20 @@ typeWithA tpa = loop
then return ()
else Left (TypeError ctx e (InvalidHandlerOutputType kY t t''))
_ -> Left (TypeError ctx e (HandlerNotAFunction kY tX))
mapM_ process (Data.HashMap.Strict.InsOrd.toList ktsY)
mapM_ process (Dhall.Map.toList ktsY)
return t
loop ctx e@(Merge kvsX kvsY Nothing) = do
tKvsX <- fmap Dhall.Core.normalize (loop ctx kvsX)
ktsX <- case tKvsX of
Record kts -> return kts
_ -> Left (TypeError ctx e (MustMergeARecord kvsX tKvsX))
let ksX = Data.Set.fromList (Data.HashMap.Strict.InsOrd.keys ktsX)
let ksX = Data.Set.fromList (Dhall.Map.keys ktsX)

tKvsY <- fmap Dhall.Core.normalize (loop ctx kvsY)
ktsY <- case tKvsY of
Union kts -> return kts
_ -> Left (TypeError ctx e (MustMergeUnion kvsY tKvsY))
let ksY = Data.Set.fromList (Data.HashMap.Strict.InsOrd.keys ktsY)
let ksY = Data.Set.fromList (Dhall.Map.keys ktsY)

let diffX = Data.Set.difference ksX ksY
let diffY = Data.Set.difference ksY ksX
@@ -729,12 +722,12 @@ typeWithA tpa = loop
then return ()
else Left (TypeError ctx e (UnusedHandler diffX))

(kX, t) <- case Data.HashMap.Strict.InsOrd.toList ktsX of
(kX, t) <- case Dhall.Map.toList ktsX of
[] -> Left (TypeError ctx e MissingMergeType)
(kX, Pi y _ t):_ -> return (kX, Dhall.Core.shift (-1) (V y 0) t)
(kX, tX ):_ -> Left (TypeError ctx e (HandlerNotAFunction kX tX))
let process (kY, tY) = do
case Data.HashMap.Strict.InsOrd.lookup kY ktsX of
case Dhall.Map.lookup kY ktsX of
Nothing -> Left (TypeError ctx e (MissingHandler diffY))
Just tX ->
case tX of
@@ -747,7 +740,7 @@ typeWithA tpa = loop
then return ()
else Left (TypeError ctx e (HandlerOutputTypeMismatch kX t kY t''))
_ -> Left (TypeError ctx e (HandlerNotAFunction kY tX))
mapM_ process (Data.HashMap.Strict.InsOrd.toList ktsY)
mapM_ process (Dhall.Map.toList ktsY)
return t
loop ctx e@(Constructors t ) = do
_ <- loop ctx t
@@ -758,14 +751,14 @@ typeWithA tpa = loop

let adapt k t_ = Pi k t_ (Union kts)

return (Record (Data.HashMap.Strict.InsOrd.mapWithKey adapt kts))
return (Record (Dhall.Map.mapWithKey adapt kts))
loop ctx e@(Field r x ) = do
t <- fmap Dhall.Core.normalize (loop ctx r)
case t of
Record kts -> do
_ <- loop ctx t

case Data.HashMap.Strict.InsOrd.lookup x kts of
case Dhall.Map.lookup x kts of
Just t' -> return t'
Nothing -> Left (TypeError ctx e (MissingField x t))
_ -> do
@@ -778,10 +771,10 @@ typeWithA tpa = loop
_ <- loop ctx t

let process k =
case Data.HashMap.Strict.InsOrd.lookup k kts of
case Dhall.Map.lookup k kts of
Just t' -> return (k, t')
Nothing -> Left (TypeError ctx e (MissingField k t))
let adapt = Record . Data.HashMap.Strict.InsOrd.fromList
let adapt = Record . Dhall.Map.fromList
fmap adapt (traverse process (Data.Set.toList xs))
_ -> do
let text = Dhall.Pretty.Internal.docToStrictText (Dhall.Pretty.Internal.prettyLabels xs)
13 changes: 6 additions & 7 deletions tests/QuickCheck.hs
Original file line number Diff line number Diff line change
@@ -8,8 +8,7 @@ module QuickCheck where

import Codec.Serialise (DeserialiseFailure(..))
import Control.Monad (guard)
import Data.Hashable (Hashable)
import Data.HashMap.Strict.InsOrd (InsOrdHashMap)
import Dhall.Map (Map)
import Dhall.Core
( Chunks(..)
, Const(..)
@@ -33,7 +32,7 @@ import Test.Tasty (TestTree)

import qualified Codec.Serialise
import qualified Data.Coerce
import qualified Data.HashMap.Strict.InsOrd
import qualified Dhall.Map
import qualified Data.Sequence
import qualified Dhall.Binary
import qualified Dhall.Core
@@ -111,16 +110,16 @@ integer =
, (1, fmap (\x -> x - (2 ^ (64 :: Int))) arbitrary)
]

instance (Eq k, Hashable k, Arbitrary k, Arbitrary v) => Arbitrary (InsOrdHashMap k v) where
instance (Ord k, Arbitrary k, Arbitrary v) => Arbitrary (Map k v) where
arbitrary = do
n <- Test.QuickCheck.choose (0, 2)
kvs <- Test.QuickCheck.vectorOf n ((,) <$> arbitrary <*> arbitrary)
return (Data.HashMap.Strict.InsOrd.fromList kvs)
return (Dhall.Map.fromList kvs)

shrink =
map Data.HashMap.Strict.InsOrd.fromList
map Dhall.Map.fromList
. shrink
. Data.HashMap.Strict.InsOrd.toList
. Dhall.Map.toList

instance (Arbitrary s, Arbitrary a) => Arbitrary (Chunks s a) where
arbitrary = do
24 changes: 14 additions & 10 deletions tests/Regression.hs
Original file line number Diff line number Diff line change
@@ -5,13 +5,13 @@
module Regression where

import qualified Control.Exception
import qualified Data.HashMap.Strict.InsOrd
import qualified Data.Text.Lazy.IO
import qualified Data.Text.Prettyprint.Doc
import qualified Data.Text.Prettyprint.Doc.Render.Text
import qualified Dhall
import qualified Dhall.Context
import qualified Dhall.Core
import qualified Dhall.Map
import qualified Dhall.Parser
import qualified Dhall.Pretty
import qualified Dhall.TypeCheck
@@ -52,21 +52,25 @@ data Foo = Foo Integer Bool | Bar Bool Bool Bool | Baz Integer Integer
unnamedFields :: TestTree
unnamedFields = Test.Tasty.HUnit.testCase "Unnamed Fields" (do
let ty = Dhall.auto :: Dhall.Type Foo
Test.Tasty.HUnit.assertEqual "Good type" (Dhall.expected ty) (Dhall.Core.Union (
Data.HashMap.Strict.InsOrd.fromList [
("Bar",Dhall.Core.Record (Data.HashMap.Strict.InsOrd.fromList [
("_1",Dhall.Core.Bool),("_2",Dhall.Core.Bool),("_3",Dhall.Core.Bool)]))
, ("Baz",Dhall.Core.Record (Data.HashMap.Strict.InsOrd.fromList [
("_1",Dhall.Core.Integer),("_2",Dhall.Core.Integer)]))
,("Foo",Dhall.Core.Record (Data.HashMap.Strict.InsOrd.fromList [
("_1",Dhall.Core.Integer),("_2",Dhall.Core.Bool)]))]))
Test.Tasty.HUnit.assertEqual "Good type" (Dhall.expected ty)
(Dhall.Core.Union
(Dhall.Map.fromList
[ ("Foo",Dhall.Core.Record (Dhall.Map.fromList [
("_1",Dhall.Core.Integer),("_2",Dhall.Core.Bool)]))
, ("Bar",Dhall.Core.Record (Dhall.Map.fromList [
("_1",Dhall.Core.Bool),("_2",Dhall.Core.Bool),("_3",Dhall.Core.Bool)]))
, ("Baz",Dhall.Core.Record (Dhall.Map.fromList [
("_1",Dhall.Core.Integer),("_2",Dhall.Core.Integer)]))
]
)
)

let inj = Dhall.inject :: Dhall.InputType Foo
Test.Tasty.HUnit.assertEqual "Good Inject" (Dhall.declared inj) (Dhall.expected ty)

let tu_ty = Dhall.auto :: Dhall.Type (Integer, Bool)
Test.Tasty.HUnit.assertEqual "Auto Tuple" (Dhall.expected tu_ty) (Dhall.Core.Record (
Data.HashMap.Strict.InsOrd.fromList [ ("_1",Dhall.Core.Integer),("_2",Dhall.Core.Bool) ]))
Dhall.Map.fromList [ ("_1",Dhall.Core.Integer),("_2",Dhall.Core.Bool) ]))

let tu_in = Dhall.inject :: Dhall.InputType (Integer, Bool)
Test.Tasty.HUnit.assertEqual "Inj. Tuple" (Dhall.declared tu_in) (Dhall.expected tu_ty)