Add support for empty alternatives (#863)
... as standardized in https://github.com/dhall-lang/dhall-lang/pull/438 This also adds `dhall-json` support for empty alternatives In particular, this translates empty alternatives to strings encoding the alternative name ```haskell -- ./example.dhall let Role = < Wizard | Fighter | Rogue > in [ Role.Wizard, Role.Fighter ] ``` ``` $ dhall-to-json <<< './example.dhall' ["Wizard","Fighter"] ```
This commit is contained in:
parent
bf067eeb69
commit
a2ab6a59ec
|
@ -272,7 +272,7 @@ dhallToJSON e0 = loop (Dhall.Core.normalize e0)
|
|||
(Dhall.Core.TextLit
|
||||
(Dhall.Core.Chunks [] nestedField)
|
||||
)
|
||||
[ ("Inline", Dhall.Core.Record []) ]
|
||||
[ ("Inline", Just (Dhall.Core.Record [])) ]
|
||||
)
|
||||
] -> do
|
||||
contents' <- loop contents
|
||||
|
@ -303,7 +303,7 @@ dhallToJSON e0 = loop (Dhall.Core.normalize e0)
|
|||
, Dhall.Core.UnionLit
|
||||
"Inline"
|
||||
(Dhall.Core.RecordLit [])
|
||||
[ ("Nested", Dhall.Core.Text) ]
|
||||
[ ("Nested", Just Dhall.Core.Text) ]
|
||||
)
|
||||
] -> do
|
||||
let contents' =
|
||||
|
@ -322,6 +322,8 @@ dhallToJSON e0 = loop (Dhall.Core.normalize e0)
|
|||
a' <- traverse loop a
|
||||
return (Data.Aeson.toJSON (Dhall.Map.toMap a'))
|
||||
Dhall.Core.UnionLit _ b _ -> loop b
|
||||
Dhall.Core.App (Dhall.Core.Field (Dhall.Core.Union _) _) b -> loop b
|
||||
Dhall.Core.Field (Dhall.Core.Union _) k -> return (toJSON k)
|
||||
_ -> Left (Unsupported e)
|
||||
|
||||
toOrderedList :: Ord k => Map k v -> [(k, v)]
|
||||
|
@ -671,13 +673,13 @@ convertToHomogeneousMaps (Conversion {..}) e0 = loop (Dhall.Core.normalize e0)
|
|||
Dhall.Core.Union a ->
|
||||
Dhall.Core.Union a'
|
||||
where
|
||||
a' = fmap loop a
|
||||
a' = fmap (fmap loop) a
|
||||
|
||||
Dhall.Core.UnionLit a b c ->
|
||||
Dhall.Core.UnionLit a b' c'
|
||||
where
|
||||
b' = loop b
|
||||
c' = fmap loop c
|
||||
b' = loop b
|
||||
c' = fmap (fmap loop) c
|
||||
|
||||
Dhall.Core.Combine a b ->
|
||||
Dhall.Core.Combine a' b'
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit b1c9e532e66dc1a5d60ddc9a84139212fb1f44a1
|
||||
Subproject commit 9303e67aa71d28b2a95d93f7ef910f6e714069e6
|
|
@ -909,7 +909,8 @@ instance GenericInterpret V1 where
|
|||
|
||||
expected = Union mempty
|
||||
|
||||
unsafeExpectUnion :: Text -> Expr Src X -> Dhall.Map.Map Text (Expr Src X)
|
||||
unsafeExpectUnion
|
||||
:: Text -> Expr Src X -> Dhall.Map.Map Text (Maybe (Expr Src X))
|
||||
unsafeExpectUnion _ (Union kts) =
|
||||
kts
|
||||
unsafeExpectUnion name expression =
|
||||
|
@ -924,7 +925,9 @@ unsafeExpectRecord name expression =
|
|||
(name <> ": Unexpected constructor: " <> Dhall.Core.pretty expression)
|
||||
|
||||
unsafeExpectUnionLit
|
||||
:: Text -> Expr Src X -> (Text, Expr Src X, Dhall.Map.Map Text (Expr Src X))
|
||||
:: Text
|
||||
-> Expr Src X
|
||||
-> (Text, Expr Src X, Dhall.Map.Map Text (Maybe (Expr Src X)))
|
||||
unsafeExpectUnionLit _ (UnionLit k v kts) =
|
||||
(k, v, kts)
|
||||
unsafeExpectUnionLit name expression =
|
||||
|
@ -938,6 +941,11 @@ unsafeExpectRecordLit name expression =
|
|||
Dhall.Core.internalError
|
||||
(name <> ": Unexpected constructor: " <> Dhall.Core.pretty expression)
|
||||
|
||||
possible :: Expr s a -> Maybe (Expr s a)
|
||||
possible e = case e of
|
||||
RecordLit m | null m -> Nothing
|
||||
_ -> Just e
|
||||
|
||||
instance (Constructor c1, Constructor c2, GenericInterpret f1, GenericInterpret f2) => GenericInterpret (M1 C c1 f1 :+: M1 C c2 f2) where
|
||||
genericAutoWith options@(InterpretOptions {..}) = pure (Type {..})
|
||||
where
|
||||
|
@ -957,7 +965,10 @@ instance (Constructor c1, Constructor c2, GenericInterpret f1, GenericInterpret
|
|||
extract _ = Nothing
|
||||
|
||||
expected =
|
||||
Union (Dhall.Map.fromList [(nameL, expectedL), (nameR, expectedR)])
|
||||
Union
|
||||
(Dhall.Map.fromList
|
||||
[(nameL, possible expectedL), (nameR, possible expectedR)]
|
||||
)
|
||||
|
||||
Type extractL expectedL = evalState (genericAutoWith options) 1
|
||||
Type extractR expectedR = evalState (genericAutoWith options) 1
|
||||
|
@ -976,7 +987,7 @@ instance (Constructor c, GenericInterpret (f :+: g), GenericInterpret h) => Gene
|
|||
extract _ = Nothing
|
||||
|
||||
expected =
|
||||
Union (Dhall.Map.insert name expectedR ktsL)
|
||||
Union (Dhall.Map.insert name (possible expectedR) ktsL)
|
||||
|
||||
Type extractL expectedL = evalState (genericAutoWith options) 1
|
||||
Type extractR expectedR = evalState (genericAutoWith options) 1
|
||||
|
@ -997,7 +1008,7 @@ instance (Constructor c, GenericInterpret f, GenericInterpret (g :+: h)) => Gene
|
|||
extract _ = Nothing
|
||||
|
||||
expected =
|
||||
Union (Dhall.Map.insert name expectedL ktsR)
|
||||
Union (Dhall.Map.insert name (possible expectedL) ktsR)
|
||||
|
||||
Type extractL expectedL = evalState (genericAutoWith options) 1
|
||||
Type extractR expectedR = evalState (genericAutoWith options) 1
|
||||
|
@ -1248,13 +1259,22 @@ instance (Constructor c1, Constructor c2, GenericInject f1, GenericInject f2) =>
|
|||
genericInjectWith options@(InterpretOptions {..}) = pure (InputType {..})
|
||||
where
|
||||
embed (L1 (M1 l)) =
|
||||
UnionLit keyL (embedL l) (Dhall.Map.singleton keyR declaredR)
|
||||
UnionLit
|
||||
keyL
|
||||
(embedL l)
|
||||
(Dhall.Map.singleton keyR (possible declaredR))
|
||||
|
||||
embed (R1 (M1 r)) =
|
||||
UnionLit keyR (embedR r) (Dhall.Map.singleton keyL declaredL)
|
||||
UnionLit
|
||||
keyR
|
||||
(embedR r)
|
||||
(Dhall.Map.singleton keyL (possible declaredL))
|
||||
|
||||
declared =
|
||||
Union (Dhall.Map.fromList [(keyL, declaredL), (keyR, declaredR)])
|
||||
Union
|
||||
(Dhall.Map.fromList
|
||||
[(keyL, possible declaredL), (keyR, possible declaredR)]
|
||||
)
|
||||
|
||||
nL :: M1 i c1 f1 a
|
||||
nL = undefined
|
||||
|
@ -1272,7 +1292,10 @@ instance (Constructor c, GenericInject (f :+: g), GenericInject h) => GenericInj
|
|||
genericInjectWith options@(InterpretOptions {..}) = pure (InputType {..})
|
||||
where
|
||||
embed (L1 l) =
|
||||
UnionLit keyL valL (Dhall.Map.insert keyR declaredR ktsL')
|
||||
UnionLit
|
||||
keyL
|
||||
valL
|
||||
(Dhall.Map.insert keyR (possible declaredR) ktsL')
|
||||
where
|
||||
(keyL, valL, ktsL') =
|
||||
unsafeExpectUnionLit "genericInjectWith (:+:)" (embedL l)
|
||||
|
@ -1283,7 +1306,7 @@ instance (Constructor c, GenericInject (f :+: g), GenericInject h) => GenericInj
|
|||
|
||||
keyR = constructorModifier (Data.Text.pack (conName nR))
|
||||
|
||||
declared = Union (Dhall.Map.insert keyR declaredR ktsL)
|
||||
declared = Union (Dhall.Map.insert keyR (possible declaredR) ktsL)
|
||||
|
||||
InputType embedL declaredL = evalState (genericInjectWith options) 1
|
||||
InputType embedR declaredR = evalState (genericInjectWith options) 1
|
||||
|
@ -1295,7 +1318,10 @@ 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 (Dhall.Map.insert keyL declaredL ktsR')
|
||||
UnionLit
|
||||
keyR
|
||||
valR
|
||||
(Dhall.Map.insert keyL (possible declaredL) ktsR')
|
||||
where
|
||||
(keyR, valR, ktsR') =
|
||||
unsafeExpectUnionLit "genericInjectWith (:+:)" (embedR r)
|
||||
|
@ -1305,7 +1331,7 @@ instance (Constructor c, GenericInject f, GenericInject (g :+: h)) => GenericInj
|
|||
|
||||
keyL = constructorModifier (Data.Text.pack (conName nL))
|
||||
|
||||
declared = Union (Dhall.Map.insert keyL declaredL ktsR)
|
||||
declared = Union (Dhall.Map.insert keyL (possible declaredL) ktsR)
|
||||
|
||||
InputType embedL declaredL = evalState (genericInjectWith options) 1
|
||||
InputType embedR declaredR = evalState (genericInjectWith options) 1
|
||||
|
@ -1513,7 +1539,7 @@ union (UnionType (Data.Functor.Compose.Compose mp)) = Type
|
|||
, expected = Union expect
|
||||
}
|
||||
where
|
||||
expect = Dhall.expected <$> mp
|
||||
expect = (possible . Dhall.expected) <$> mp
|
||||
extractF e0 = do
|
||||
UnionLit fld e1 rest <- Just e0
|
||||
t <- Dhall.Map.lookup fld mp
|
||||
|
@ -1689,10 +1715,12 @@ inputUnion ( UnionInputType ( Data.Functor.Product.Pair ( Control.Applicative.Co
|
|||
InputType
|
||||
{ embed = \x ->
|
||||
let (name, y) = embedF x
|
||||
in UnionLit name y (Dhall.Map.delete name fields)
|
||||
in UnionLit name y (Dhall.Map.delete name fields')
|
||||
, declared =
|
||||
Union fields
|
||||
Union fields'
|
||||
}
|
||||
where
|
||||
fields' = fmap possible fields
|
||||
|
||||
inputConstructorWith
|
||||
:: Text
|
||||
|
|
|
@ -341,9 +341,14 @@ encode (Union xTs₀) =
|
|||
TList [ TInt 11, TMap xTs₁ ]
|
||||
where
|
||||
xTs₁ = do
|
||||
(x₀, _T₀) <- Dhall.Map.toList (Dhall.Map.sort xTs₀)
|
||||
(x₀, mT₀) <- Dhall.Map.toList (Dhall.Map.sort xTs₀)
|
||||
|
||||
let x₁ = TString x₀
|
||||
let _T₁ = encode _T₀
|
||||
|
||||
let _T₁ = case mT₀ of
|
||||
Nothing -> TNull
|
||||
Just _T₀ -> encode _T₀
|
||||
|
||||
return (x₁, _T₁)
|
||||
encode (UnionLit x t₀ yTs₀) =
|
||||
TList [ TInt 12, TString x, t₁, TMap yTs₁ ]
|
||||
|
@ -351,9 +356,11 @@ encode (UnionLit x t₀ yTs₀) =
|
|||
t₁ = encode t₀
|
||||
|
||||
yTs₁ = do
|
||||
(y₀, _T₀) <- Dhall.Map.toList (Dhall.Map.sort yTs₀)
|
||||
(y₀, mT₀) <- Dhall.Map.toList (Dhall.Map.sort yTs₀)
|
||||
let y₁ = TString y₀
|
||||
let _T₁ = encode _T₀
|
||||
let _T₁ = case mT₀ of
|
||||
Just _T₀ -> encode _T₀
|
||||
Nothing -> TNull
|
||||
return (y₁, _T₁)
|
||||
encode (BoolLit b) =
|
||||
TBool b
|
||||
|
@ -656,9 +663,11 @@ decodeMaybe (TList (TInt 10 : t₁ : xs₁)) = do
|
|||
return (Project t₀ (Dhall.Set.fromList xs₀))
|
||||
decodeMaybe (TList [ TInt 11, TMap xTs₁ ]) = do
|
||||
let process (TString x, _T₁) = do
|
||||
_T₀ <- decodeMaybe _T₁
|
||||
mT₀ <- case _T₁ of
|
||||
TNull -> return Nothing
|
||||
_ -> fmap Just (decodeMaybe _T₁)
|
||||
|
||||
return (x, _T₀)
|
||||
return (x, mT₀)
|
||||
process _ =
|
||||
empty
|
||||
|
||||
|
@ -669,7 +678,9 @@ decodeMaybe (TList [ TInt 12, TString x, t₁, TMap yTs₁ ]) = do
|
|||
t₀ <- decodeMaybe t₁
|
||||
|
||||
let process (TString y, _T₁) = do
|
||||
_T₀ <- decodeMaybe _T₁
|
||||
_T₀ <- case _T₁ of
|
||||
TNull -> return Nothing
|
||||
_ -> fmap Just (decodeMaybe _T₁)
|
||||
|
||||
return (y, _T₀)
|
||||
process _ =
|
||||
|
|
|
@ -438,10 +438,10 @@ data Expr s a
|
|||
| Record (Map Text (Expr s a))
|
||||
-- | > RecordLit [(k1, v1), (k2, v2)] ~ { k1 = v1, k2 = v2 }
|
||||
| RecordLit (Map Text (Expr s a))
|
||||
-- | > Union [(k1, t1), (k2, t2)] ~ < k1 : t1 | k2 : t2 >
|
||||
| Union (Map Text (Expr s a))
|
||||
-- | > UnionLit k v [(k1, t1), (k2, t2)] ~ < k = v | k1 : t1 | k2 : t2 >
|
||||
| UnionLit Text (Expr s a) (Map Text (Expr s a))
|
||||
-- | > Union [(k1, Just t1), (k2, Nothing)] ~ < k1 : t1 | k2 >
|
||||
| Union (Map Text (Maybe (Expr s a)))
|
||||
-- | > UnionLit k v [(k1, Just t1), (k2, Nothing)] ~ < k = v | k1 : t1 | k2 >
|
||||
| UnionLit Text (Expr s a) (Map Text (Maybe (Expr s a)))
|
||||
-- | > Combine x y ~ x ∧ y
|
||||
| Combine (Expr s a) (Expr s a)
|
||||
-- | > CombineTypes x y ~ x ⩓ y
|
||||
|
@ -522,8 +522,8 @@ instance Functor (Expr s) where
|
|||
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 (Union u) = Union (fmap (fmap (fmap f)) u)
|
||||
fmap f (UnionLit v e u) = UnionLit v (fmap f e) (fmap (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)
|
||||
|
@ -599,8 +599,8 @@ instance Monad (Expr s) where
|
|||
OptionalBuild >>= _ = OptionalBuild
|
||||
Record a >>= k = Record (fmap (>>= k) a)
|
||||
RecordLit a >>= k = RecordLit (fmap (>>= k) a)
|
||||
Union a >>= k = Union (fmap (>>= k) a)
|
||||
UnionLit a b c >>= k = UnionLit a (b >>= k) (fmap (>>= k) c)
|
||||
Union a >>= k = Union (fmap (fmap (>>= k)) a)
|
||||
UnionLit a b c >>= k = UnionLit a (b >>= k) (fmap (fmap (>>= k)) c)
|
||||
Combine a b >>= k = Combine (a >>= k) (b >>= k)
|
||||
CombineTypes a b >>= k = CombineTypes (a >>= k) (b >>= k)
|
||||
Prefer a b >>= k = Prefer (a >>= k) (b >>= k)
|
||||
|
@ -666,8 +666,8 @@ instance Bifunctor Expr where
|
|||
first _ OptionalBuild = OptionalBuild
|
||||
first k (Record a ) = Record (fmap (first k) a)
|
||||
first k (RecordLit a ) = RecordLit (fmap (first k) a)
|
||||
first k (Union a ) = Union (fmap (first k) a)
|
||||
first k (UnionLit a b c ) = UnionLit a (first k b) (fmap (first k) c)
|
||||
first k (Union a ) = Union (fmap (fmap (first k)) a)
|
||||
first k (UnionLit a b c ) = UnionLit a (first k b) (fmap (fmap (first k)) c)
|
||||
first k (Combine a b ) = Combine (first k a) (first k b)
|
||||
first k (CombineTypes a b ) = CombineTypes (first k a) (first k b)
|
||||
first k (Prefer a b ) = Prefer (first k a) (first k b)
|
||||
|
@ -925,11 +925,11 @@ shift d v (RecordLit a) = RecordLit a'
|
|||
a' = fmap (shift d v) a
|
||||
shift d v (Union a) = Union a'
|
||||
where
|
||||
a' = fmap (shift d v) a
|
||||
a' = fmap (fmap (shift d v)) a
|
||||
shift d v (UnionLit a b c) = UnionLit a b' c'
|
||||
where
|
||||
b' = shift d v b
|
||||
c' = fmap (shift d v) c
|
||||
b' = shift d v b
|
||||
c' = fmap (fmap (shift d v)) c
|
||||
shift d v (Combine a b) = Combine a' b'
|
||||
where
|
||||
a' = shift d v a
|
||||
|
@ -1095,10 +1095,19 @@ subst x e (Some a) = Some a'
|
|||
subst _ _ None = None
|
||||
subst _ _ OptionalFold = OptionalFold
|
||||
subst _ _ OptionalBuild = OptionalBuild
|
||||
subst x e (Record kts) = Record (fmap (subst x e) kts)
|
||||
subst x e (RecordLit kvs) = RecordLit (fmap (subst x e) kvs)
|
||||
subst x e (Union kts) = Union (fmap (subst x e) kts)
|
||||
subst x e (UnionLit a b kts) = UnionLit a (subst x e b) (fmap (subst x e) kts)
|
||||
subst x e (Record kts) = Record kts'
|
||||
where
|
||||
kts' = fmap (subst x e) kts
|
||||
subst x e (RecordLit kvs) = RecordLit kvs'
|
||||
where
|
||||
kvs' = fmap (subst x e) kvs
|
||||
subst x e (Union kts) = Union kts'
|
||||
where
|
||||
kts' = fmap (fmap (subst x e)) kts
|
||||
subst x e (UnionLit a b kts) = UnionLit a b' kts'
|
||||
where
|
||||
b' = subst x e b
|
||||
kts' = fmap (fmap (subst x e)) kts
|
||||
subst x e (Combine a b) = Combine a' b'
|
||||
where
|
||||
a' = subst x e a
|
||||
|
@ -1381,13 +1390,13 @@ alphaNormalize (RecordLit kvs₀) =
|
|||
alphaNormalize (Union kts₀) =
|
||||
Union kts₁
|
||||
where
|
||||
kts₁ = fmap alphaNormalize kts₀
|
||||
kts₁ = fmap (fmap alphaNormalize) kts₀
|
||||
alphaNormalize (UnionLit k v₀ kts₀) =
|
||||
UnionLit k v₁ kts₁
|
||||
where
|
||||
v₁ = alphaNormalize v₀
|
||||
|
||||
kts₁ = fmap alphaNormalize kts₀
|
||||
kts₁ = fmap (fmap alphaNormalize) kts₀
|
||||
alphaNormalize (Combine l₀ r₀) =
|
||||
Combine l₁ r₁
|
||||
where
|
||||
|
@ -1465,7 +1474,7 @@ boundedType Text = True
|
|||
boundedType (App List _) = False
|
||||
boundedType (App Optional t) = boundedType t
|
||||
boundedType (Record kvs) = all boundedType kvs
|
||||
boundedType (Union kvs) = all boundedType kvs
|
||||
boundedType (Union kvs) = all (all boundedType) kvs
|
||||
boundedType _ = False
|
||||
|
||||
-- | Remove all `Note` constructors from an `Expr` (i.e. de-`Note`)
|
||||
|
@ -1527,8 +1536,8 @@ denote OptionalFold = OptionalFold
|
|||
denote OptionalBuild = OptionalBuild
|
||||
denote (Record a ) = Record (fmap denote a)
|
||||
denote (RecordLit a ) = RecordLit (fmap denote a)
|
||||
denote (Union a ) = Union (fmap denote a)
|
||||
denote (UnionLit a b c ) = UnionLit a (denote b) (fmap denote c)
|
||||
denote (Union a ) = Union (fmap (fmap denote) a)
|
||||
denote (UnionLit a b c ) = UnionLit a (denote b) (fmap (fmap denote) c)
|
||||
denote (Combine a b ) = Combine (denote a) (denote b)
|
||||
denote (CombineTypes a b ) = CombineTypes (denote a) (denote b)
|
||||
denote (Prefer a b ) = Prefer (denote a) (denote b)
|
||||
|
@ -1856,11 +1865,11 @@ normalizeWithM ctx e0 = loop (denote e0)
|
|||
kvs' = traverse loop kvs
|
||||
Union kts -> Union . Dhall.Map.sort <$> kts'
|
||||
where
|
||||
kts' = traverse loop kts
|
||||
kts' = traverse (traverse loop) kts
|
||||
UnionLit k v kvs -> UnionLit k <$> v' <*> (Dhall.Map.sort <$> kvs')
|
||||
where
|
||||
v' = loop v
|
||||
kvs' = traverse loop kvs
|
||||
v' = loop v
|
||||
kvs' = traverse (traverse loop) kvs
|
||||
Combine x y -> decide <$> loop x <*> loop y
|
||||
where
|
||||
decide (RecordLit m) r | Data.Foldable.null m =
|
||||
|
@ -1901,6 +1910,22 @@ normalizeWithM ctx e0 = loop (denote e0)
|
|||
case Dhall.Map.lookup kY kvsX of
|
||||
Just vX -> loop (App vX vY)
|
||||
Nothing -> Merge x' y' <$> t'
|
||||
Field (Union ktsY) kY ->
|
||||
case Dhall.Map.lookup kY ktsY of
|
||||
Just Nothing ->
|
||||
case Dhall.Map.lookup kY kvsX of
|
||||
Just vX -> return vX
|
||||
Nothing -> Merge x' y' <$> t'
|
||||
_ ->
|
||||
Merge x' y' <$> t'
|
||||
App (Field (Union ktsY) kY) vY ->
|
||||
case Dhall.Map.lookup kY ktsY of
|
||||
Just (Just _) ->
|
||||
case Dhall.Map.lookup kY kvsX of
|
||||
Just vX -> loop (App vX vY)
|
||||
Nothing -> Merge x' y' <$> t'
|
||||
_ ->
|
||||
Merge x' y' <$> t'
|
||||
_ -> Merge x' y' <$> t'
|
||||
_ -> Merge x' y' <$> t'
|
||||
where
|
||||
|
@ -1912,13 +1937,6 @@ normalizeWithM ctx e0 = loop (denote e0)
|
|||
case Dhall.Map.lookup x kvs of
|
||||
Just v -> loop v
|
||||
Nothing -> Field <$> (RecordLit <$> traverse loop kvs) <*> pure x
|
||||
Union kvs ->
|
||||
case Dhall.Map.lookup x kvs of
|
||||
Just t_ -> Lam x <$> t' <*> pure (UnionLit x (Var (V x 0)) rest)
|
||||
where
|
||||
t' = loop t_
|
||||
rest = Dhall.Map.delete x kvs
|
||||
Nothing -> Field <$> (Union <$> traverse loop kvs) <*> pure x
|
||||
_ -> pure (Field r' x)
|
||||
Project r xs -> do
|
||||
r' <- loop r
|
||||
|
@ -2129,8 +2147,8 @@ isNormalized e0 = loop (denote e0)
|
|||
OptionalBuild -> True
|
||||
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
|
||||
Union kts -> Dhall.Map.isSorted kts && all (all loop) kts
|
||||
UnionLit _ v kvs -> loop v && Dhall.Map.isSorted kvs && all (all loop) kvs
|
||||
Combine x y -> loop x && loop y && decide x y
|
||||
where
|
||||
decide (RecordLit m) _ | Data.Foldable.null m = False
|
||||
|
@ -2334,8 +2352,9 @@ subExpressions _ OptionalFold = pure OptionalFold
|
|||
subExpressions _ OptionalBuild = pure OptionalBuild
|
||||
subExpressions f (Record a) = Record <$> traverse f a
|
||||
subExpressions f ( RecordLit a ) = RecordLit <$> traverse f a
|
||||
subExpressions f (Union a) = Union <$> traverse f a
|
||||
subExpressions f (UnionLit a b c) = UnionLit a <$> f b <*> traverse f c
|
||||
subExpressions f (Union a) = Union <$> traverse (traverse f) a
|
||||
subExpressions f (UnionLit a b c) =
|
||||
UnionLit a <$> f b <*> traverse (traverse f) c
|
||||
subExpressions f (Combine a b) = Combine <$> f a <*> f b
|
||||
subExpressions f (CombineTypes a b) = CombineTypes <$> f a <*> f b
|
||||
subExpressions f (Prefer a b) = Prefer <$> f a <*> f b
|
||||
|
|
|
@ -255,7 +255,17 @@ diffKeyVals
|
|||
-> Map Text (Expr s a)
|
||||
-> Map Text (Expr s a)
|
||||
-> [Diff]
|
||||
diffKeyVals assign kvsL kvsR =
|
||||
diffKeyVals assign = diffKeysWith assign diffVals
|
||||
where
|
||||
diffVals l r = assign <> " " <> diffExpression l r
|
||||
|
||||
diffKeysWith
|
||||
:: Diff
|
||||
-> (a -> a -> Diff)
|
||||
-> Map Text a
|
||||
-> Map Text a
|
||||
-> [Diff]
|
||||
diffKeysWith assign diffVals kvsL kvsR =
|
||||
diffFieldNames <> diffFieldValues <> (if anyEqual then [ ignore ] else [])
|
||||
where
|
||||
ksL = Data.Set.fromList (Dhall.Map.keys kvsL)
|
||||
|
@ -274,7 +284,7 @@ diffKeyVals assign kvsL kvsR =
|
|||
<> ignore
|
||||
]
|
||||
|
||||
shared = Dhall.Map.intersectionWith diffExpression kvsL kvsR
|
||||
shared = Dhall.Map.intersectionWith diffVals kvsL kvsR
|
||||
|
||||
diffFieldValues =
|
||||
filter (not . same) (Dhall.Map.foldMapWithKey adapt shared)
|
||||
|
@ -405,8 +415,10 @@ diffRecordLit kvsL kvsR = braced (diffKeyVals equals kvsL kvsR)
|
|||
|
||||
diffUnion
|
||||
:: (Eq a, Pretty a)
|
||||
=> Map Text (Expr s a) -> Map Text (Expr s a) -> Diff
|
||||
diffUnion kvsL kvsR = angled (diffKeyVals colon kvsL kvsR)
|
||||
=> Map Text (Maybe (Expr s a)) -> Map Text (Maybe (Expr s a)) -> Diff
|
||||
diffUnion kvsL kvsR = angled (diffKeysWith colon diffVals kvsL kvsR)
|
||||
where
|
||||
diffVals = diffMaybe (colon <> " ") diffExpression
|
||||
|
||||
diffUnionLit
|
||||
:: (Eq a, Pretty a)
|
||||
|
@ -414,8 +426,8 @@ diffUnionLit
|
|||
-> Text
|
||||
-> Expr s a
|
||||
-> Expr s a
|
||||
-> Map Text (Expr s a)
|
||||
-> Map Text (Expr s a)
|
||||
-> Map Text (Maybe (Expr s a))
|
||||
-> Map Text (Maybe (Expr s a))
|
||||
-> Diff
|
||||
diffUnionLit kL kR vL vR kvsL kvsR =
|
||||
langle
|
||||
|
@ -424,8 +436,10 @@ diffUnionLit kL kR vL vR kvsL kvsR =
|
|||
<> equals
|
||||
<> " "
|
||||
<> format " " (diffExpression vL vR)
|
||||
<> halfAngled (diffKeyVals equals kvsL kvsR)
|
||||
<> halfAngled (diffKeysWith colon diffVals kvsL kvsR)
|
||||
where
|
||||
diffVals = diffMaybe (colon <> " ") diffExpression
|
||||
|
||||
halfAngled = enclosed (pipe <> " ") (pipe <> " ") rangle
|
||||
|
||||
listSkeleton :: Diff
|
||||
|
|
|
@ -888,8 +888,8 @@ loadWith expr₀ = case expr₀ of
|
|||
OptionalBuild -> pure OptionalBuild
|
||||
Record a -> Record <$> mapM loadWith a
|
||||
RecordLit a -> RecordLit <$> mapM loadWith a
|
||||
Union a -> Union <$> mapM loadWith a
|
||||
UnionLit a b c -> UnionLit <$> pure a <*> loadWith b <*> mapM loadWith c
|
||||
Union a -> Union <$> mapM (mapM loadWith) a
|
||||
UnionLit a b c -> UnionLit <$> pure a <*> loadWith b <*> mapM (mapM loadWith) c
|
||||
Combine a b -> Combine <$> loadWith a <*> loadWith b
|
||||
CombineTypes a b -> CombineTypes <$> loadWith a <*> loadWith b
|
||||
Prefer a b -> Prefer <$> loadWith a <*> loadWith b
|
||||
|
|
|
@ -578,14 +578,12 @@ completeExpression embedded = completeExpression_
|
|||
kvs <- Text.Megaparsec.many (do
|
||||
_bar
|
||||
c <- label
|
||||
_colon
|
||||
d <- expression
|
||||
d <- optional (do _colon; expression)
|
||||
return (c, d) )
|
||||
return (UnionLit a b, kvs)
|
||||
|
||||
let alternative1 = do
|
||||
_colon
|
||||
b <- expression
|
||||
b <- optional (do _colon; expression)
|
||||
|
||||
let alternative2 = do
|
||||
_bar
|
||||
|
|
|
@ -849,19 +849,21 @@ prettyCharacterSet characterSet = prettyExpression
|
|||
| otherwise
|
||||
= braces (map (prettyKeyValue equals) (Dhall.Map.toList a))
|
||||
|
||||
prettyUnion :: Pretty a => Map Text (Expr s a) -> Doc Ann
|
||||
prettyAlternative (key, Just val) = prettyKeyValue colon (key, val)
|
||||
prettyAlternative (key, Nothing ) = duplicate (prettyLabel key)
|
||||
|
||||
prettyUnion :: Pretty a => Map Text (Maybe (Expr s a)) -> Doc Ann
|
||||
prettyUnion =
|
||||
angles . map (prettyKeyValue colon) . Dhall.Map.toList
|
||||
angles . map prettyAlternative . Dhall.Map.toList
|
||||
|
||||
prettyUnionLit
|
||||
:: Pretty a => Text -> Expr s a -> Map Text (Expr s a) -> Doc Ann
|
||||
:: Pretty a
|
||||
=> Text -> Expr s a -> Map Text (Maybe (Expr s a)) -> Doc Ann
|
||||
prettyUnionLit a b c =
|
||||
angles (front : map adapt (Dhall.Map.toList c))
|
||||
angles (front : map prettyAlternative (Dhall.Map.toList c))
|
||||
where
|
||||
front = prettyKeyValue equals (a, b)
|
||||
|
||||
adapt = prettyKeyValue colon
|
||||
|
||||
prettyChunks :: Pretty a => Chunks s a -> Doc Ann
|
||||
prettyChunks (Chunks a b) =
|
||||
if any (\(builder, _) -> hasNewLine builder) a || hasNewLine b
|
||||
|
|
|
@ -480,23 +480,28 @@ completeFunc reversedPrev word
|
|||
where
|
||||
listCompletion = map simpleCompletion . filter (word `isPrefixOf`)
|
||||
|
||||
algebraicComplete :: [Text.Text] -> Dhall.Expr Dhall.Src Dhall.X -> [Text.Text]
|
||||
algebraicComplete
|
||||
:: [Text.Text] -> Dhall.Expr Dhall.Src Dhall.X -> [Text.Text]
|
||||
algebraicComplete subFields expr =
|
||||
let keys = fmap ("." <>) . Map.keys
|
||||
|
||||
withMap m
|
||||
| [] <- subFields = keys m
|
||||
-- Stop on last subField (we care about the keys at this level)
|
||||
| [_] <- subFields = keys m
|
||||
| f:fs <- subFields =
|
||||
maybe
|
||||
[]
|
||||
(fmap (("." <> f) <>) . algebraicComplete fs)
|
||||
(Map.lookup f m)
|
||||
withMap m =
|
||||
case subFields of
|
||||
[] -> keys m
|
||||
-- Stop on last subField (we care about the keys at this level)
|
||||
[_] -> keys m
|
||||
f:fs ->
|
||||
case Map.lookup f m of
|
||||
Nothing ->
|
||||
[]
|
||||
Just Nothing ->
|
||||
keys m
|
||||
Just (Just e) ->
|
||||
fmap (("." <> f) <>) (algebraicComplete fs e)
|
||||
|
||||
in case expr of
|
||||
Dhall.Core.Record m -> withMap m
|
||||
Dhall.Core.RecordLit m -> withMap m
|
||||
Dhall.Core.Record m -> withMap (fmap Just m)
|
||||
Dhall.Core.RecordLit m -> withMap (fmap Just m)
|
||||
Dhall.Core.Union m -> withMap m
|
||||
Dhall.Core.UnionLit _ _ m -> withMap m
|
||||
_ -> []
|
||||
|
|
|
@ -1060,18 +1060,36 @@ import Dhall
|
|||
-- the @Natural@ alternative and the @Right@ tag is used for the @Bool@
|
||||
-- alternative.
|
||||
--
|
||||
-- A union literal specifies the value of one alternative and the types of the
|
||||
-- remaining alternatives. For example, both of the following union literals
|
||||
-- have the same type, which is the above union type:
|
||||
-- You can specify the value of a union constructor like this:
|
||||
--
|
||||
-- > < Left = 0 | Right : Bool >
|
||||
-- > let Union = < Left : Natural | Right : Bool>
|
||||
-- >
|
||||
-- > [ Union.Left 0, Union.Right True ] : List Union
|
||||
--
|
||||
-- > < Right = True | Left : Natural >
|
||||
-- In other words, you can access a union constructor as a field of a union
|
||||
-- type and use that constructor to wrap a value of a type appropriate for
|
||||
-- that alternative. In the above example, the @Left@ constructor can wrap
|
||||
-- a @Natural@ value and the @Right@ constructor can wrap a @Bool@ value. We
|
||||
-- can also confirm that by inspecting their type:
|
||||
--
|
||||
-- > $ echo '< Left : Natural | Right : Bool>' > ./Union
|
||||
--
|
||||
-- > $ dhall --annotate <<< '(./Union).Left'
|
||||
-- > < Left : Natural | Right : Bool >.Left
|
||||
-- > : ∀(Left : Natural) → < Left : Natural | Right : Bool >
|
||||
--
|
||||
-- > $ dhall --annotate <<< '(./Union).Right'
|
||||
-- > < Left : Natural | Right : Bool >.Right
|
||||
-- > : ∀(Right : Bool) → < Left : Natural | Right : Bool >
|
||||
--
|
||||
-- In other words, the @Left@ constructor is a function from a @Natural@ to a
|
||||
-- value of our @Union@ type and the @Right@ constructor is a separate function
|
||||
-- from a @Bool@ to that same @Union@ type.
|
||||
--
|
||||
-- You can consume a union using the built-in @merge@ function. For example,
|
||||
-- suppose we want to convert our union to a @Bool@ but we want to behave
|
||||
-- differently depending on whether or not the union is a @Natural@ wrapped in
|
||||
-- the @Left@ alternative or a @Bool@ wrapped in the @Right@ alternative. We
|
||||
-- the @Left@ constructor or a @Bool@ wrapped in the @Right@ constructor . We
|
||||
-- would write:
|
||||
--
|
||||
-- > $ cat > process <<EOF
|
||||
|
@ -1085,18 +1103,10 @@ import Dhall
|
|||
--
|
||||
-- Now our @./process@ function can handle both alternatives:
|
||||
--
|
||||
-- > $ dhall
|
||||
-- > ./process < Left = 3 | Right : Bool >
|
||||
-- > <Ctrl-D>
|
||||
-- > Bool
|
||||
-- >
|
||||
-- > $ dhall <<< './process ((./Union).Left 3)'
|
||||
-- > False
|
||||
--
|
||||
-- > $ dhall
|
||||
-- > ./process < Right = True | Left : Natural >
|
||||
-- > <Ctrl-D>
|
||||
-- > Bool
|
||||
-- >
|
||||
-- > $ dhall <<< './process ((./Union).Right True)'
|
||||
-- > True
|
||||
--
|
||||
-- Every @merge@ has the following form:
|
||||
|
@ -1112,66 +1122,54 @@ import Dhall
|
|||
-- The @merge@ function selects which function to apply from the record based on
|
||||
-- which alternative the union selects:
|
||||
--
|
||||
-- > merge { Foo = f, ... } < Foo = x | ... > : t = f x : t
|
||||
-- > merge { Foo = f, ... } (< … >.Foo x) = f x
|
||||
--
|
||||
-- So, for example:
|
||||
--
|
||||
-- > merge { Left = Natural/even, Right = λ(b : Bool) → b } < Left = 3 | Right : Bool > : Bool
|
||||
-- > = Natural/even 3 : Bool
|
||||
-- > merge { Left = Natural/even, Right = λ(b : Bool) → b } (< Left : Natural | Right : Bool >.Left 3)
|
||||
-- > = Natural/even 3
|
||||
-- > = False
|
||||
--
|
||||
-- ... and similarly:
|
||||
--
|
||||
-- > merge { Left = Natural/even, Right = λ(b : Bool) → b } < Right = True | Left : Natural > : Bool
|
||||
-- > = (λ(b : Bool) → b) True : Bool
|
||||
-- > merge { Left = Natural/even, Right = λ(b : Bool) → b } (< Left : Natural | Right : Bool >.Right True)
|
||||
-- > = (λ(b : Bool) → b) True
|
||||
-- > = True
|
||||
--
|
||||
-- Notice that each handler has to return the same type of result (@Bool@ in
|
||||
-- this case) which must also match the declared result type of the @merge@.
|
||||
-- this case).
|
||||
--
|
||||
-- You can also omit the type annotation when merging a union with one or more
|
||||
-- alternatives, like this:
|
||||
--
|
||||
-- > merge { Left = Natural/even, Right = λ(b : Bool) → b } < Right = True | Left : Natural >
|
||||
--
|
||||
-- You can also store more than one value or less than one value within
|
||||
-- alternatives using Dhall's support for anonymous records. You can nest an
|
||||
-- anonymous record within a union such as in this type:
|
||||
-- You can also store more than one value within alternatives using Dhall's
|
||||
-- support for anonymous records. You can nest an anonymous record within a
|
||||
-- union such as in this type:
|
||||
--
|
||||
-- > < Empty : {} | Person : { name : Text, age : Natural } >
|
||||
--
|
||||
-- You can even go a step further and omit the type of an alternative if it
|
||||
-- stores no data, like this:
|
||||
--
|
||||
-- > < Empty | Person : { name : Text, age : Natural } >
|
||||
--
|
||||
--
|
||||
-- This union of records resembles following equivalent Haskell data type:
|
||||
--
|
||||
-- > data Example = Empty | Person { name :: Text, age :: Text }
|
||||
--
|
||||
-- You could resemble Haskell further by defining convenient constructors for
|
||||
-- each alternative, like this:
|
||||
-- Empty alternatives like @Empty@ require no argument:
|
||||
--
|
||||
-- > let Empty = < Empty = {=} | Person : { name : Text, age : Natural } >
|
||||
-- > let Person =
|
||||
-- > λ(p : { name : Text, age : Natural }) → < Person = p | Empty : {} >
|
||||
-- > in [ Empty
|
||||
-- > , Person { name = "John", age = 23 }
|
||||
-- > , Person { name = "Amy" , age = 25 }
|
||||
-- > , Empty
|
||||
-- > ]
|
||||
--
|
||||
-- ... but there is no need to do so, since the Dhall language auto-generates
|
||||
-- constructors for each alternative. You can access each constructor as if it
|
||||
-- were a field of the union type:
|
||||
--
|
||||
-- > let MyType = < Empty : {} | Person : { name : Text, age : Natural } >
|
||||
-- > in [ MyType.Empty {=}
|
||||
-- > let MyType = < Empty | Person : { name : Text, age : Natural } >
|
||||
-- >
|
||||
-- > in [ MyType.Empty -- Note the absence of any argument to `Empty`
|
||||
-- > , MyType.Person { name = "John", age = 23 }
|
||||
-- > , MyType.Person { name = "Amy" , age = 25 }
|
||||
-- > ]
|
||||
--
|
||||
-- You can also extract fields during pattern matching such as in the following
|
||||
-- function which renders each value to `Text`:
|
||||
-- ... and when you @merge@ an empty alternative the correspond handler takes no
|
||||
-- argument:
|
||||
--
|
||||
-- > λ(x : < Empty : {} | Person : { name : Text, age : Natural } >)
|
||||
-- > λ(x : < Empty | Person : { name : Text, age : Natural } >)
|
||||
-- > → merge
|
||||
-- > { Empty = λ(_ : {}) → "Unknown"
|
||||
-- > { Empty = "Unknown" -- Note the absence of a `λ`
|
||||
-- >
|
||||
-- > , Person =
|
||||
-- > λ(person : { name : Text, age : Natural })
|
||||
|
|
|
@ -25,6 +25,7 @@ import Control.Exception (Exception)
|
|||
import Data.Data (Data(..))
|
||||
import Data.Foldable (forM_, toList)
|
||||
import Data.List.NonEmpty (NonEmpty(..))
|
||||
import Data.Monoid (First(..))
|
||||
import Data.Sequence (Seq, ViewL(..))
|
||||
import Data.Semigroup (Semigroup(..))
|
||||
import Data.Set (Set)
|
||||
|
@ -555,11 +556,13 @@ typeWithA tpa = loop
|
|||
kts <- Dhall.Map.traverseWithKey process kvs
|
||||
return (Record kts)
|
||||
loop ctx e@(Union kts ) = do
|
||||
case Dhall.Map.uncons kts of
|
||||
let nonEmpty k mt = First (fmap (\t -> (k, t)) mt)
|
||||
|
||||
case getFirst (Dhall.Map.foldMapWithKey nonEmpty kts) of
|
||||
Nothing -> do
|
||||
return (Const Type)
|
||||
|
||||
Just (k0, t0, rest) -> do
|
||||
Just (k0, t0) -> do
|
||||
s0 <- fmap Dhall.Core.normalize (loop ctx t0)
|
||||
|
||||
c0 <- case s0 of
|
||||
|
@ -569,7 +572,10 @@ typeWithA tpa = loop
|
|||
_ -> do
|
||||
Left (TypeError ctx e (InvalidAlternativeType k0 t0))
|
||||
|
||||
let process k t = do
|
||||
let process _ Nothing = do
|
||||
return ()
|
||||
|
||||
process k (Just t) = do
|
||||
s <- fmap Dhall.Core.normalize (loop ctx t)
|
||||
|
||||
c <- case s of
|
||||
|
@ -583,7 +589,7 @@ typeWithA tpa = loop
|
|||
then return ()
|
||||
else Left (TypeError ctx e (AlternativeAnnotationMismatch k t c k0 t0 c0))
|
||||
|
||||
Dhall.Map.unorderedTraverseWithKey_ process rest
|
||||
Dhall.Map.unorderedTraverseWithKey_ process kts
|
||||
|
||||
return (Const c0)
|
||||
loop ctx e@(UnionLit k v kts) = do
|
||||
|
@ -591,7 +597,7 @@ typeWithA tpa = loop
|
|||
Just _ -> Left (TypeError ctx e (DuplicateAlternative k))
|
||||
Nothing -> return ()
|
||||
t <- loop ctx v
|
||||
let union = Union (Dhall.Map.insert k (Dhall.Core.normalize t) kts)
|
||||
let union = Union (Dhall.Map.insert k (Just (Dhall.Core.normalize t)) kts)
|
||||
_ <- loop ctx union
|
||||
return union
|
||||
loop ctx e@(Combine kvsX kvsY) = do
|
||||
|
@ -711,19 +717,20 @@ typeWithA tpa = loop
|
|||
else Left (TypeError ctx e (RecordMismatch '⫽' kvsX kvsY constX constY))
|
||||
|
||||
return (Record (Dhall.Map.union ktsY ktsX))
|
||||
loop ctx e@(Merge kvsX kvsY (Just t)) = do
|
||||
_ <- loop ctx t
|
||||
|
||||
loop ctx e@(Merge kvsX kvsY mT₁) = do
|
||||
tKvsX <- fmap Dhall.Core.normalize (loop ctx kvsX)
|
||||
ktsX <- case tKvsX of
|
||||
|
||||
ktsX <- case tKvsX of
|
||||
Record kts -> return kts
|
||||
_ -> Left (TypeError ctx e (MustMergeARecord kvsX tKvsX))
|
||||
let ksX = Data.Set.fromList (Dhall.Map.keys ktsX)
|
||||
|
||||
tKvsY <- fmap Dhall.Core.normalize (loop ctx kvsY)
|
||||
ktsY <- case tKvsY of
|
||||
|
||||
ktsY <- case tKvsY of
|
||||
Union kts -> return kts
|
||||
_ -> Left (TypeError ctx e (MustMergeUnion kvsY tKvsY))
|
||||
|
||||
let ksX = Data.Set.fromList (Dhall.Map.keys ktsX)
|
||||
let ksY = Data.Set.fromList (Dhall.Map.keys ktsY)
|
||||
|
||||
let diffX = Data.Set.difference ksX ksY
|
||||
|
@ -733,62 +740,69 @@ typeWithA tpa = loop
|
|||
then return ()
|
||||
else Left (TypeError ctx e (UnusedHandler diffX))
|
||||
|
||||
let process (kY, tY) = do
|
||||
(mKX, _T₁) <- do
|
||||
case mT₁ of
|
||||
Just _T₁ -> do
|
||||
return (Nothing, _T₁)
|
||||
|
||||
Nothing -> do
|
||||
case Dhall.Map.uncons ktsX of
|
||||
Nothing -> do
|
||||
Left (TypeError ctx e MissingMergeType)
|
||||
|
||||
Just (kX, tX, _) -> do
|
||||
_T₁ <- do
|
||||
case Dhall.Map.lookup kX ktsY of
|
||||
Nothing -> do
|
||||
Left (TypeError ctx e (UnusedHandler diffX))
|
||||
|
||||
Just Nothing -> do
|
||||
return tX
|
||||
|
||||
Just (Just _) ->
|
||||
case tX of
|
||||
Pi x _A₀ _T₀ -> do
|
||||
return (Dhall.Core.shift (-1) (V x 0) _T₀)
|
||||
_ -> do
|
||||
Left (TypeError ctx e (HandlerNotAFunction kX tX))
|
||||
|
||||
return (Just kX, _T₁)
|
||||
|
||||
_ <- loop ctx _T₁
|
||||
|
||||
let process kY mTY = do
|
||||
case Dhall.Map.lookup kY ktsX of
|
||||
Nothing -> Left (TypeError ctx e (MissingHandler diffY))
|
||||
Just tX ->
|
||||
case tX of
|
||||
Pi y tY' t' -> do
|
||||
if Dhall.Core.judgmentallyEqual tY tY'
|
||||
then return ()
|
||||
else Left (TypeError ctx e (HandlerInputTypeMismatch kY tY tY'))
|
||||
let t'' = Dhall.Core.shift (-1) (V y 0) t'
|
||||
if Dhall.Core.judgmentallyEqual t t''
|
||||
then return ()
|
||||
else Left (TypeError ctx e (InvalidHandlerOutputType kY t t''))
|
||||
_ -> Left (TypeError ctx e (HandlerNotAFunction kY tX))
|
||||
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 (Dhall.Map.keys ktsX)
|
||||
Nothing -> do
|
||||
Left (TypeError ctx e (MissingHandler diffY))
|
||||
|
||||
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 (Dhall.Map.keys ktsY)
|
||||
Just tX -> do
|
||||
_T₃ <- do
|
||||
case mTY of
|
||||
Nothing -> do
|
||||
return tX
|
||||
Just _A₁ -> do
|
||||
case tX of
|
||||
Pi x _A₀ _T₂ -> do
|
||||
if Dhall.Core.judgmentallyEqual _A₀ _A₁
|
||||
then return ()
|
||||
else Left (TypeError ctx e (HandlerInputTypeMismatch kY _A₁ _A₀))
|
||||
|
||||
let diffX = Data.Set.difference ksX ksY
|
||||
let diffY = Data.Set.difference ksY ksX
|
||||
return (Dhall.Core.shift (-1) (V x 0) _T₂)
|
||||
_ -> do
|
||||
Left (TypeError ctx e (HandlerNotAFunction kY tX))
|
||||
|
||||
if Data.Set.null diffX
|
||||
then return ()
|
||||
else Left (TypeError ctx e (UnusedHandler diffX))
|
||||
if Dhall.Core.judgmentallyEqual _T₁ _T₃
|
||||
then return ()
|
||||
else
|
||||
case mKX of
|
||||
Nothing -> do
|
||||
Left (TypeError ctx e (InvalidHandlerOutputType kY _T₁ _T₃))
|
||||
Just kX -> do
|
||||
Left (TypeError ctx e (HandlerOutputTypeMismatch kX _T₁ kY _T₃))
|
||||
|
||||
(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 Dhall.Map.lookup kY ktsX of
|
||||
Nothing -> Left (TypeError ctx e (MissingHandler diffY))
|
||||
Just tX ->
|
||||
case tX of
|
||||
Pi y tY' t' -> do
|
||||
if Dhall.Core.judgmentallyEqual tY tY'
|
||||
then return ()
|
||||
else Left (TypeError ctx e (HandlerInputTypeMismatch kY tY tY'))
|
||||
let t'' = Dhall.Core.shift (-1) (V y 0) t'
|
||||
if Dhall.Core.judgmentallyEqual t t''
|
||||
then return ()
|
||||
else Left (TypeError ctx e (HandlerOutputTypeMismatch kX t kY t''))
|
||||
_ -> Left (TypeError ctx e (HandlerNotAFunction kY tX))
|
||||
mapM_ process (Dhall.Map.toList ktsY)
|
||||
return t
|
||||
Dhall.Map.unorderedTraverseWithKey_ process ktsY
|
||||
|
||||
return _T₁
|
||||
loop ctx e@(Field r x ) = do
|
||||
t <- fmap Dhall.Core.normalize (loop ctx r)
|
||||
|
||||
|
@ -805,7 +819,8 @@ typeWithA tpa = loop
|
|||
case Dhall.Core.normalize r of
|
||||
Union kts ->
|
||||
case Dhall.Map.lookup x kts of
|
||||
Just t' -> return (Pi x t' (Union kts))
|
||||
Just (Just t') -> return (Pi x t' (Union kts))
|
||||
Just Nothing -> return (Union kts)
|
||||
Nothing -> Left (TypeError ctx e (MissingField x t))
|
||||
r' -> Left (TypeError ctx e (CantAccess text r' t))
|
||||
_ -> do
|
||||
|
|
|
@ -45,6 +45,9 @@ tests =
|
|||
, shouldNormalize
|
||||
"the // operator and sort the fields"
|
||||
"success/simple/sortOperator"
|
||||
, shouldNormalize
|
||||
"enums"
|
||||
"success/simple/enum"
|
||||
, multiline
|
||||
]
|
||||
|
||||
|
@ -194,174 +197,175 @@ preludeExamples =
|
|||
unitTests :: TestTree
|
||||
unitTests =
|
||||
testGroup "Unit tests"
|
||||
[ shouldOnlyNormalize "ListNormalizeElements"
|
||||
, shouldOnlyNormalize "TextNormalizeInterpolations"
|
||||
, shouldOnlyNormalize "RecordTypeEmpty"
|
||||
, shouldOnlyNormalize "MergeNormalizeArguments"
|
||||
, shouldOnlyNormalize "OperatorAndNormalizeArguments"
|
||||
, shouldOnlyNormalize "OperatorEqualEquivalentArguments"
|
||||
, shouldOnlyNormalize "ListIndexedEmpty"
|
||||
, shouldOnlyNormalize "OperatorListConcatenateLhsEmpty"
|
||||
, shouldOnlyNormalize "Variable"
|
||||
, shouldOnlyNormalize "RecursiveRecordTypeMergeRhsEmpty"
|
||||
, shouldOnlyNormalize "NaturalToInteger"
|
||||
, shouldOnlyNormalize "ListReverse"
|
||||
, shouldOnlyNormalize "MergeWithType"
|
||||
, shouldOnlyNormalize "OperatorOrLhsFalse"
|
||||
, shouldOnlyNormalize "IntegerPositive"
|
||||
, shouldOnlyNormalize "OperatorTimesRhsOne"
|
||||
, shouldOnlyNormalize "NaturalOdd"
|
||||
, shouldOnlyNormalize "RecursiveRecordMergeLhsEmpty"
|
||||
, shouldOnlyNormalize "RightBiasedRecordMergeNormalizeArguments"
|
||||
, shouldOnlyNormalize "UnionType"
|
||||
, shouldOnlyNormalize "IntegerNegative"
|
||||
, shouldOnlyNormalize "NaturalEven"
|
||||
, shouldOnlyNormalize "OperatorAndRhsTrue"
|
||||
, shouldOnlyNormalize "NaturalBuildImplementation"
|
||||
, shouldOnlyNormalize "RecursiveRecordMergeCollision"
|
||||
, shouldOnlyNormalize "RecursiveRecordMergeNormalizeArguments"
|
||||
, shouldOnlyNormalize "OperatorAndLhsTrue"
|
||||
, shouldOnlyNormalize "OperatorPlusOneAndOne"
|
||||
, shouldOnlyNormalize "IntegerToDouble12"
|
||||
, shouldOnlyNormalize "IntegerToDouble-12"
|
||||
, shouldOnlyNormalize "IntegerShow-12"
|
||||
, shouldOnlyNormalize "ListLengthOne"
|
||||
, shouldOnlyNormalize "IntegerShow12"
|
||||
, shouldOnlyNormalize "NaturalFoldZero"
|
||||
, shouldOnlyNormalize "RecordType"
|
||||
, shouldOnlyNormalize "IfFalse"
|
||||
, shouldOnlyNormalize "DoubleShow"
|
||||
, shouldOnlyNormalize "OptionalBuildFoldFusion"
|
||||
, shouldOnlyNormalize "NaturalShow"
|
||||
, shouldOnlyNormalize "ListLength"
|
||||
, shouldOnlyNormalize "RecursiveRecordTypeMergeCollision"
|
||||
, shouldOnlyNormalize "RecordEmpty"
|
||||
, shouldOnlyNormalize "TextLiteral"
|
||||
, shouldOnlyNormalize "RecordSelectionNormalizeArguments"
|
||||
, shouldOnlyNormalize "OptionalFold"
|
||||
, shouldOnlyNormalize "IfTrivial"
|
||||
, shouldOnlyNormalize "ListBuild"
|
||||
, shouldOnlyNormalize "OperatorTextConcatenateLhsEmpty"
|
||||
, shouldOnlyNormalize "LetWithType"
|
||||
, shouldOnlyNormalize "OptionalFoldSome"
|
||||
, shouldOnlyNormalize "OptionalBuild"
|
||||
, shouldOnlyNormalize "ListFoldOne"
|
||||
, shouldOnlyNormalize "ListLast"
|
||||
, shouldOnlyNormalize "ListReverseEmpty"
|
||||
, shouldOnlyNormalize "NaturalEvenZero"
|
||||
, shouldOnlyNormalize "RecursiveRecordTypeMergeNoCollision"
|
||||
, shouldOnlyNormalize "NaturalToIntegerOne"
|
||||
, shouldOnlyNormalize "Natural"
|
||||
, shouldOnlyNormalize "ListIndexed"
|
||||
, shouldOnlyNormalize "Integer"
|
||||
, shouldOnlyNormalize "NaturalIsZero"
|
||||
, shouldOnlyNormalize "OperatorNotEqualLhsFalse"
|
||||
, shouldOnlyNormalize "NaturalIsZeroZero"
|
||||
, shouldOnlyNormalize "OperatorPlusNormalizeArguments"
|
||||
, shouldOnlyNormalize "RecordSelection"
|
||||
, shouldOnlyNormalize "OperatorListConcatenateListList"
|
||||
, shouldOnlyNormalize "OperatorTextConcatenateNormalizeArguments"
|
||||
, shouldOnlyNormalize "True"
|
||||
, shouldOnlyNormalize "Bool"
|
||||
, shouldOnlyNormalize "OperatorNotEqualNormalizeArguments"
|
||||
, shouldOnlyNormalize "RightBiasedRecordMergeLhsEmpty"
|
||||
, shouldOnlyNormalize "UnionNormalizeArguments"
|
||||
, shouldOnlyNormalize "OperatorAndLhsFalse"
|
||||
, shouldOnlyNormalize "RecordProjection"
|
||||
, shouldOnlyNormalize "OptionalBuildImplementation"
|
||||
, shouldOnlyNormalize "OperatorEqualNormalizeArguments"
|
||||
, shouldOnlyNormalize "Merge"
|
||||
, shouldOnlyNormalize "Type"
|
||||
, shouldOnlyNormalize "OperatorListConcatenateRhsEmpty"
|
||||
, shouldOnlyNormalize "RightBiasedRecordMergeNoCollision"
|
||||
, shouldOnlyNormalize "RecursiveRecordTypeMergeLhsEmpty"
|
||||
, shouldOnlyNormalize "IfAlternativesIdentical"
|
||||
, shouldOnlyNormalize "NoneNatural"
|
||||
, shouldOnlyNormalize "UnionProjectConstructor"
|
||||
, shouldOnlyNormalize "ListLastOne"
|
||||
, shouldOnlyNormalize "IntegerToDouble"
|
||||
, shouldOnlyNormalize "RightBiasedRecordMergeCollision"
|
||||
, shouldOnlyNormalize "OperatorOrRhsTrue"
|
||||
, shouldOnlyNormalize "IfTrue"
|
||||
, shouldOnlyNormalize "OperatorPlusRhsZero"
|
||||
, shouldOnlyNormalize "ListHeadOne"
|
||||
, shouldOnlyNormalize "FunctionApplicationNoSubstitute"
|
||||
, shouldOnlyNormalize "RecursiveRecordMergeRhsEmpty"
|
||||
, shouldOnlyNormalize "ListReverseTwo"
|
||||
, shouldOnlyNormalize "OperatorOrRhsFalse"
|
||||
, shouldOnlyNormalize "NaturalOddZero"
|
||||
, shouldOnlyNormalize "UnionTypeNormalizeArguments"
|
||||
, shouldOnlyNormalize "TextInterpolate"
|
||||
, shouldOnlyNormalize "Let"
|
||||
, shouldOnlyNormalize "OperatorTimesLhsOne"
|
||||
, shouldOnlyNormalize "OperatorOrLhsTrue"
|
||||
, shouldOnlyNormalize "OperatorPlusLhsZero"
|
||||
, shouldOnlyNormalize "FunctionNormalizeArguments"
|
||||
, shouldOnlyNormalize "ListLastEmpty"
|
||||
, shouldOnlyNormalize "UnionTypeEmpty"
|
||||
, shouldOnlyNormalize "TextShowAllEscapes"
|
||||
, shouldOnlyNormalize "RecursiveRecordMergeNoCollision"
|
||||
, shouldOnlyNormalize "ListNormalizeTypeAnnotation"
|
||||
, shouldOnlyNormalize "NaturalFoldOne"
|
||||
, shouldOnlyNormalize "OperatorAndEquivalentArguments"
|
||||
, shouldOnlyNormalize "SomeNormalizeArguments"
|
||||
, shouldOnlyNormalize "MergeWithTypeNormalizeArguments"
|
||||
, shouldOnlyNormalize "OperatorOrNormalizeArguments"
|
||||
, shouldOnlyNormalize "RecordProjectionNormalizeArguments"
|
||||
, shouldOnlyNormalize "FunctionApplicationSubstitute"
|
||||
, shouldOnlyNormalize "OperatorOrEquivalentArguments"
|
||||
, shouldOnlyNormalize "NaturalFold"
|
||||
, shouldOnlyNormalize "NaturalEvenOne"
|
||||
, shouldOnlyNormalize "OperatorTextConcatenateRhsEmpty"
|
||||
, shouldOnlyNormalize "DoubleLiteral"
|
||||
, shouldOnlyNormalize "ListHeadEmpty"
|
||||
, shouldOnlyNormalize "FunctionApplicationCapture"
|
||||
, shouldOnlyNormalize "RecordProjectionEmpty"
|
||||
, shouldOnlyNormalize "List"
|
||||
, shouldOnlyNormalize "NaturalOddOne"
|
||||
, shouldOnlyNormalize "ListFold"
|
||||
, shouldOnlyNormalize "OperatorEqualRhsTrue"
|
||||
, shouldOnlyNormalize "DoubleShowValue"
|
||||
, shouldOnlyNormalize "OperatorNotEqualEquivalentArguments"
|
||||
, shouldOnlyNormalize "Text"
|
||||
, shouldOnlyNormalize "ListIndexedOne"
|
||||
, shouldOnlyNormalize "IntegerShow"
|
||||
, shouldOnlyNormalize "Optional"
|
||||
, shouldOnlyNormalize "OperatorTimesNormalizeArguments"
|
||||
, shouldOnlyNormalize "NaturalLiteral"
|
||||
, shouldOnlyNormalize "ListHead"
|
||||
, shouldOnlyNormalize "ListBuildFoldFusion"
|
||||
, shouldOnlyNormalize "NaturalIsZeroOne"
|
||||
, shouldOnlyNormalize "OperatorListConcatenateNormalizeArguments"
|
||||
, shouldOnlyNormalize "OperatorTimesRhsZero"
|
||||
[ shouldOnlyNormalize "Bool"
|
||||
, shouldOnlyNormalize "Double"
|
||||
, shouldOnlyNormalize "OperatorTimesLhsZero"
|
||||
, shouldOnlyNormalize "ListFoldEmpty"
|
||||
, shouldOnlyNormalize "DoubleLiteral"
|
||||
, shouldOnlyNormalize "DoubleShow"
|
||||
, shouldOnlyNormalize "DoubleShowValue"
|
||||
, shouldOnlyNormalize "FunctionApplicationCapture"
|
||||
, shouldOnlyNormalize "FunctionApplicationNoSubstitute"
|
||||
, shouldOnlyNormalize "FunctionApplicationNormalizeArguments"
|
||||
, shouldOnlyNormalize "NaturalShowOne"
|
||||
, shouldOnlyNormalize "OptionalFoldNone"
|
||||
, shouldOnlyNormalize "TextShow"
|
||||
, shouldOnlyNormalize "Kind"
|
||||
, shouldOnlyNormalize "Sort"
|
||||
, shouldOnlyNormalize "OperatorTextConcatenateTextText"
|
||||
, shouldOnlyNormalize "FunctionApplicationSubstitute"
|
||||
, shouldOnlyNormalize "FunctionNormalizeArguments"
|
||||
, shouldOnlyNormalize "FunctionTypeNormalizeArguments"
|
||||
, shouldOnlyNormalize "OperatorNotEqualRhsFalse"
|
||||
, shouldOnlyNormalize "IfAlternativesIdentical"
|
||||
, shouldOnlyNormalize "IfFalse"
|
||||
, shouldOnlyNormalize "IfNormalizePredicateAndBranches"
|
||||
, shouldOnlyNormalize "IfTrivial"
|
||||
, shouldOnlyNormalize "IfTrue"
|
||||
, shouldOnlyNormalize "Integer"
|
||||
, shouldOnlyNormalize "IntegerNegative"
|
||||
, shouldOnlyNormalize "IntegerPositive"
|
||||
, shouldOnlyNormalize "IntegerShow"
|
||||
, shouldOnlyNormalize "IntegerShow-12"
|
||||
, shouldOnlyNormalize "IntegerShow12"
|
||||
, shouldOnlyNormalize "IntegerToDouble"
|
||||
, shouldOnlyNormalize "IntegerToDouble-12"
|
||||
, shouldOnlyNormalize "IntegerToDouble12"
|
||||
, shouldOnlyNormalize "Kind"
|
||||
, shouldOnlyNormalize "Let"
|
||||
, shouldOnlyNormalize "LetWithType"
|
||||
, shouldOnlyNormalize "List"
|
||||
, shouldOnlyNormalize "ListBuild"
|
||||
, shouldOnlyNormalize "ListBuildFoldFusion"
|
||||
, shouldOnlyNormalize "ListBuildImplementation"
|
||||
, shouldOnlyNormalize "ListFold"
|
||||
, shouldOnlyNormalize "ListFoldEmpty"
|
||||
, shouldOnlyNormalize "ListFoldOne"
|
||||
, shouldOnlyNormalize "ListHead"
|
||||
, shouldOnlyNormalize "ListHeadEmpty"
|
||||
, shouldOnlyNormalize "ListHeadOne"
|
||||
, shouldOnlyNormalize "ListIndexed"
|
||||
, shouldOnlyNormalize "ListIndexedEmpty"
|
||||
, shouldOnlyNormalize "ListIndexedOne"
|
||||
, shouldOnlyNormalize "ListLast"
|
||||
, shouldOnlyNormalize "ListLastEmpty"
|
||||
, shouldOnlyNormalize "ListLastOne"
|
||||
, shouldOnlyNormalize "ListLength"
|
||||
, shouldOnlyNormalize "ListLengthEmpty"
|
||||
, shouldOnlyNormalize "ListLengthOne"
|
||||
, shouldOnlyNormalize "ListNormalizeElements"
|
||||
, shouldOnlyNormalize "ListNormalizeTypeAnnotation"
|
||||
, shouldOnlyNormalize "ListReverse"
|
||||
, shouldOnlyNormalize "ListReverseEmpty"
|
||||
, shouldOnlyNormalize "ListReverseTwo"
|
||||
, shouldOnlyNormalize "Merge"
|
||||
, shouldOnlyNormalize "MergeEmptyAlternative"
|
||||
, shouldOnlyNormalize "MergeNormalizeArguments"
|
||||
, shouldOnlyNormalize "MergeWithType"
|
||||
, shouldOnlyNormalize "MergeWithTypeNormalizeArguments"
|
||||
, shouldOnlyNormalize "Natural"
|
||||
, shouldOnlyNormalize "NaturalBuild"
|
||||
, shouldOnlyNormalize "NaturalBuildFoldFusion"
|
||||
, shouldOnlyNormalize "TypeAnnotation"
|
||||
, shouldOnlyNormalize "IfNormalizePredicateAndBranches"
|
||||
, shouldOnlyNormalize "OperatorEqualLhsTrue"
|
||||
, shouldOnlyNormalize "Record"
|
||||
, shouldOnlyNormalize "RecursiveRecordTypeMergeNormalizeArguments"
|
||||
, shouldOnlyNormalize "UnionNormalizeAlternatives"
|
||||
, shouldOnlyNormalize "OperatorTimesTwoAndTwo"
|
||||
, shouldOnlyNormalize "ListBuildImplementation"
|
||||
, shouldOnlyNormalize "UnionProjectConstructorNormalizeArguments"
|
||||
, shouldOnlyNormalize "NaturalBuildImplementation"
|
||||
, shouldOnlyNormalize "NaturalEven"
|
||||
, shouldOnlyNormalize "NaturalEvenOne"
|
||||
, shouldOnlyNormalize "NaturalEvenZero"
|
||||
, shouldOnlyNormalize "NaturalFold"
|
||||
, shouldOnlyNormalize "NaturalFoldOne"
|
||||
, shouldOnlyNormalize "NaturalFoldZero"
|
||||
, shouldOnlyNormalize "NaturalIsZero"
|
||||
, shouldOnlyNormalize "NaturalIsZeroOne"
|
||||
, shouldOnlyNormalize "NaturalIsZeroZero"
|
||||
, shouldOnlyNormalize "NaturalLiteral"
|
||||
, shouldOnlyNormalize "NaturalOdd"
|
||||
, shouldOnlyNormalize "NaturalOddOne"
|
||||
, shouldOnlyNormalize "NaturalOddZero"
|
||||
, shouldOnlyNormalize "NaturalShow"
|
||||
, shouldOnlyNormalize "NaturalShowOne"
|
||||
, shouldOnlyNormalize "NaturalToInteger"
|
||||
, shouldOnlyNormalize "NaturalToIntegerOne"
|
||||
, shouldOnlyNormalize "None"
|
||||
, shouldOnlyNormalize "RightBiasedRecordMergeRhsEmpty"
|
||||
, shouldOnlyNormalize "UnionSortAlternatives"
|
||||
, shouldOnlyNormalize "ListLengthEmpty"
|
||||
, shouldOnlyNormalize "NoneNatural"
|
||||
, shouldOnlyNormalize "OperatorAndEquivalentArguments"
|
||||
, shouldOnlyNormalize "OperatorAndLhsFalse"
|
||||
, shouldOnlyNormalize "OperatorAndLhsTrue"
|
||||
, shouldOnlyNormalize "OperatorAndNormalizeArguments"
|
||||
, shouldOnlyNormalize "OperatorAndRhsFalse"
|
||||
, shouldOnlyNormalize "OperatorAndRhsTrue"
|
||||
, shouldOnlyNormalize "OperatorEqualEquivalentArguments"
|
||||
, shouldOnlyNormalize "OperatorEqualLhsTrue"
|
||||
, shouldOnlyNormalize "OperatorEqualNormalizeArguments"
|
||||
, shouldOnlyNormalize "OperatorEqualRhsTrue"
|
||||
, shouldOnlyNormalize "OperatorListConcatenateLhsEmpty"
|
||||
, shouldOnlyNormalize "OperatorListConcatenateListList"
|
||||
, shouldOnlyNormalize "OperatorListConcatenateNormalizeArguments"
|
||||
, shouldOnlyNormalize "OperatorListConcatenateRhsEmpty"
|
||||
, shouldOnlyNormalize "OperatorNotEqualEquivalentArguments"
|
||||
, shouldOnlyNormalize "OperatorNotEqualLhsFalse"
|
||||
, shouldOnlyNormalize "OperatorNotEqualNormalizeArguments"
|
||||
, shouldOnlyNormalize "OperatorNotEqualRhsFalse"
|
||||
, shouldOnlyNormalize "OperatorOrEquivalentArguments"
|
||||
, shouldOnlyNormalize "OperatorOrLhsFalse"
|
||||
, shouldOnlyNormalize "OperatorOrLhsTrue"
|
||||
, shouldOnlyNormalize "OperatorOrNormalizeArguments"
|
||||
, shouldOnlyNormalize "OperatorOrRhsFalse"
|
||||
, shouldOnlyNormalize "OperatorOrRhsTrue"
|
||||
, shouldOnlyNormalize "OperatorPlusLhsZero"
|
||||
, shouldOnlyNormalize "OperatorPlusNormalizeArguments"
|
||||
, shouldOnlyNormalize "OperatorPlusOneAndOne"
|
||||
, shouldOnlyNormalize "OperatorPlusRhsZero"
|
||||
, shouldOnlyNormalize "OperatorTextConcatenateLhsEmpty"
|
||||
, shouldOnlyNormalize "OperatorTextConcatenateNormalizeArguments"
|
||||
, shouldOnlyNormalize "OperatorTextConcatenateRhsEmpty"
|
||||
, shouldOnlyNormalize "OperatorTextConcatenateTextText"
|
||||
, shouldOnlyNormalize "OperatorTimesLhsOne"
|
||||
, shouldOnlyNormalize "OperatorTimesLhsZero"
|
||||
, shouldOnlyNormalize "OperatorTimesNormalizeArguments"
|
||||
, shouldOnlyNormalize "OperatorTimesRhsOne"
|
||||
, shouldOnlyNormalize "OperatorTimesRhsZero"
|
||||
, shouldOnlyNormalize "OperatorTimesTwoAndTwo"
|
||||
, shouldOnlyNormalize "Optional"
|
||||
, shouldOnlyNormalize "OptionalBuild"
|
||||
, shouldOnlyNormalize "OptionalBuildFoldFusion"
|
||||
, shouldOnlyNormalize "OptionalBuildImplementation"
|
||||
, shouldOnlyNormalize "OptionalFold"
|
||||
, shouldOnlyNormalize "OptionalFoldNone"
|
||||
, shouldOnlyNormalize "OptionalFoldSome"
|
||||
, shouldOnlyNormalize "Record"
|
||||
, shouldOnlyNormalize "RecordEmpty"
|
||||
, shouldOnlyNormalize "RecordProjection"
|
||||
, shouldOnlyNormalize "RecordProjectionEmpty"
|
||||
, shouldOnlyNormalize "RecordProjectionNormalizeArguments"
|
||||
, shouldOnlyNormalize "RecordSelection"
|
||||
, shouldOnlyNormalize "RecordSelectionNormalizeArguments"
|
||||
, shouldOnlyNormalize "RecordType"
|
||||
, shouldOnlyNormalize "RecordTypeEmpty"
|
||||
, shouldOnlyNormalize "RecursiveRecordMergeCollision"
|
||||
, shouldOnlyNormalize "RecursiveRecordMergeLhsEmpty"
|
||||
, shouldOnlyNormalize "RecursiveRecordMergeNoCollision"
|
||||
, shouldOnlyNormalize "RecursiveRecordMergeNormalizeArguments"
|
||||
, shouldOnlyNormalize "RecursiveRecordMergeRhsEmpty"
|
||||
, shouldOnlyNormalize "RecursiveRecordTypeMergeCollision"
|
||||
, shouldOnlyNormalize "RecursiveRecordTypeMergeLhsEmpty"
|
||||
, shouldOnlyNormalize "RecursiveRecordTypeMergeNoCollision"
|
||||
, shouldOnlyNormalize "RecursiveRecordTypeMergeNormalizeArguments"
|
||||
, shouldOnlyNormalize "RecursiveRecordTypeMergeRhsEmpty"
|
||||
, shouldOnlyNormalize "RightBiasedRecordMergeCollision"
|
||||
, shouldOnlyNormalize "RightBiasedRecordMergeLhsEmpty"
|
||||
, shouldOnlyNormalize "RightBiasedRecordMergeNoCollision"
|
||||
, shouldOnlyNormalize "RightBiasedRecordMergeNormalizeArguments"
|
||||
, shouldOnlyNormalize "RightBiasedRecordMergeRhsEmpty"
|
||||
, shouldOnlyNormalize "SomeNormalizeArguments"
|
||||
, shouldOnlyNormalize "Sort"
|
||||
, shouldOnlyNormalize "Text"
|
||||
, shouldOnlyNormalize "TextInterpolate"
|
||||
, shouldOnlyNormalize "TextLiteral"
|
||||
, shouldOnlyNormalize "TextNormalizeInterpolations"
|
||||
, shouldOnlyNormalize "TextShow"
|
||||
, shouldOnlyNormalize "TextShowAllEscapes"
|
||||
, shouldOnlyNormalize "True"
|
||||
, shouldOnlyNormalize "Type"
|
||||
, shouldOnlyNormalize "TypeAnnotation"
|
||||
, shouldOnlyNormalize "UnionNormalizeAlternatives"
|
||||
, shouldOnlyNormalize "UnionNormalizeArguments"
|
||||
, shouldOnlyNormalize "UnionProjectConstructor"
|
||||
, shouldOnlyNormalize "UnionProjectConstructorNormalizeArguments"
|
||||
, shouldOnlyNormalize "UnionSortAlternatives"
|
||||
, shouldOnlyNormalize "UnionType"
|
||||
, shouldOnlyNormalize "UnionTypeEmpty"
|
||||
, shouldOnlyNormalize "UnionTypeNormalizeArguments"
|
||||
, shouldOnlyNormalize "Variable"
|
||||
]
|
||||
|
||||
alphaNormalizationTests :: TestTree
|
||||
|
|
|
@ -53,12 +53,12 @@ unnamedFields = Test.Tasty.HUnit.testCase "Unnamed Fields" (do
|
|||
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)]))
|
||||
[ ("Foo",Just (Dhall.Core.Record (Dhall.Map.fromList [
|
||||
("_1",Dhall.Core.Integer),("_2",Dhall.Core.Bool)])))
|
||||
, ("Bar",Just (Dhall.Core.Record (Dhall.Map.fromList [
|
||||
("_1",Dhall.Core.Bool),("_2",Dhall.Core.Bool),("_3",Dhall.Core.Bool)])))
|
||||
, ("Baz",Just (Dhall.Core.Record (Dhall.Map.fromList [
|
||||
("_1",Dhall.Core.Integer),("_2",Dhall.Core.Integer)])))
|
||||
]
|
||||
)
|
||||
)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
let MyType = < Empty : {} | Person : { name : Text, age : Natural } >
|
||||
in [ MyType.Empty {=}
|
||||
let MyType = < Empty | Person : { name : Text, age : Natural } >
|
||||
|
||||
in [ MyType.Empty -- Note the absence of any argument to `Empty`
|
||||
, MyType.Person { name = "John", age = 23 }
|
||||
, MyType.Person { name = "Amy" , age = 25 }
|
||||
]
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
[ < Empty = {=} | Person : { age : Natural, name : Text } >
|
||||
, < Person = { age = 23, name = "John" } | Empty : {} >
|
||||
, < Person = { age = 25, name = "Amy" } | Empty : {} >
|
||||
[ < Empty | Person : { age : Natural, name : Text } >.Empty
|
||||
, < Empty | Person : { age : Natural, name : Text } >.Person
|
||||
{ age = 23, name = "John" }
|
||||
, < Empty | Person : { age : Natural, name : Text } >.Person
|
||||
{ age = 25, name = "Amy" }
|
||||
]
|
||||
|
|
Loading…
Reference in New Issue
Block a user