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 support for accessing/projecting record type fields #2555

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dhall/dhall-lang
Submodule dhall-lang updated 47 files
+4 −4 .github/CONTRIBUTING.md
+2 −2 CHANGELOG.md
+6 −6 Prelude/Function/compose.dhall
+3 −0 Prelude/Function/composeList
+35 −0 Prelude/Function/composeList.dhall
+4 −0 Prelude/Function/package.dhall
+1 −1 Prelude/package.dhall
+0 −4 docs/discussions/Dhall-in-production.md
+5 −1 docs/howtos/Cheatsheet.md
+23 −14 docs/references/Built-in-types.md
+19 −1 docs/tutorials/Language-Tour.md
+1 −1 docs/tutorials/index.md
+15 −0 nixops/packages/Prelude_23_0_0.nix
+1 −0 nixops/store.nix
+8 −1 standard/Parser.hs
+3 −3 standard/README.md
+15 −3 standard/beta-normalization.md
+1 −1 standard/binary.md
+10 −5 standard/dhall.abnf
+1 −1 standard/function-check.md
+1 −1 standard/substitution.md
+26 −1 standard/type-inference.md
+1 −1 tests/import/success/unit/ImportRelativeToHomeB.dhall
+1 −0 tests/normalization/success/unit/RecordTypeProjectionA.dhall
+1 −0 tests/normalization/success/unit/RecordTypeProjectionB.dhall
+1 −0 tests/normalization/success/unit/RecordTypeSelectionA.dhall
+1 −0 tests/normalization/success/unit/RecordTypeSelectionB.dhall
+8 −0 tests/parser/success/binaryA.dhall
+ tests/parser/success/binaryB.dhallb
+1 −0 tests/parser/success/binaryB.diag
+8 −7 tests/type-inference/success/preludeB.dhall
+1 −0 tests/type-inference/success/unit/RecordTypeProjectionEmptyA.dhall
+1 −0 tests/type-inference/success/unit/RecordTypeProjectionEmptyB.dhall
+1 −0 tests/type-inference/success/unit/RecordTypeProjectionKindA.dhall
+1 −0 tests/type-inference/success/unit/RecordTypeProjectionKindB.dhall
+1 −0 tests/type-inference/success/unit/RecordTypeProjectionMixedA.dhall
+1 −0 tests/type-inference/success/unit/RecordTypeProjectionMixedB.dhall
+1 −0 tests/type-inference/success/unit/RecordTypeProjectionSortA.dhall
+1 −0 tests/type-inference/success/unit/RecordTypeProjectionSortB.dhall
+1 −0 tests/type-inference/success/unit/RecordTypeProjectionTypeA.dhall
+1 −0 tests/type-inference/success/unit/RecordTypeProjectionTypeB.dhall
+1 −0 tests/type-inference/success/unit/RecordTypeSelectionKindA.dhall
+1 −0 tests/type-inference/success/unit/RecordTypeSelectionKindB.dhall
+1 −0 tests/type-inference/success/unit/RecordTypeSelectionSortA.dhall
+1 −0 tests/type-inference/success/unit/RecordTypeSelectionSortB.dhall
+1 −0 tests/type-inference/success/unit/RecordTypeSelectionTypeA.dhall
+1 −0 tests/type-inference/success/unit/RecordTypeSelectionTypeB.dhall
1 change: 1 addition & 0 deletions dhall/dhall.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ Library
Dhall.Syntax.Instances.Functor
Dhall.Syntax.Instances.Lift
Dhall.Syntax.Instances.Monad
Dhall.Syntax.Instances.Monoid
Dhall.Syntax.Instances.NFData
Dhall.Syntax.Instances.Ord
Dhall.Syntax.Instances.Pretty
Expand Down
6 changes: 6 additions & 0 deletions dhall/src/Dhall/Eval.hs
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,9 @@ vField t0 k = go t0
Just (Just _) -> VPrim $ \ ~u -> VInject m k (Just u)
Just Nothing -> VInject m k Nothing
_ -> error errorMsg
VRecord m
| Just v <- Map.lookup k m -> v
| otherwise -> error errorMsg
VRecordLit m
| Just v <- Map.lookup k m -> v
| otherwise -> error errorMsg
Expand Down Expand Up @@ -414,6 +417,9 @@ vProjectByFields env t ks =
VRecordLit kvs ->
let kvs' = Map.restrictKeys kvs (Dhall.Set.toSet ks)
in VRecordLit kvs'
VRecord kTs ->
let kTs' = Map.restrictKeys kTs (Dhall.Set.toSet ks)
in VRecord kTs'
VProject t' _ ->
vProjectByFields env t' ks
VPrefer l (VRecordLit kvs) ->
Expand Down
9 changes: 9 additions & 0 deletions dhall/src/Dhall/Normalize.hs
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,11 @@ normalizeWithM ctx e0 = loop (Syntax.denote e0)
case Dhall.Map.lookup x kvs of
Just v -> pure $ recordFieldValue v
Nothing -> Field <$> (RecordLit <$> traverse (Syntax.recordFieldExprs loop) kvs) <*> pure k
Record kTs ->
case Dhall.Map.lookup x kTs of
Just _T -> pure $ recordFieldValue _T
Nothing -> Field <$> (Record <$> traverse (Syntax.recordFieldExprs loop) kTs) <*> pure k

Project r_ _ -> loop (Field r_ k)
Prefer cs _ (RecordLit kvs) r_ -> case Dhall.Map.lookup x kvs of
Just v -> pure (Field (Prefer cs PreferFromSource (singletonRecordLit v) r_) k)
Expand All @@ -684,6 +689,8 @@ normalizeWithM ctx e0 = loop (Syntax.denote e0)
case x' of
RecordLit kvs ->
pure (RecordLit (Dhall.Map.restrictKeys kvs fieldsSet))
Record kTs ->
pure (Record (Dhall.Map.restrictKeys kTs fieldsSet))
Project y _ ->
loop (Project y (Left fields))
Prefer cs _ l (RecordLit rKvs) -> do
Expand Down Expand Up @@ -980,6 +987,7 @@ isNormalized e0 = loop (Syntax.denote e0)
_ -> True
Field r (FieldSelection Nothing k Nothing) -> case r of
RecordLit _ -> False
Record _ -> False
Project _ _ -> False
Prefer _ _ (RecordLit m) _ -> Dhall.Map.keys m == [k] && loop r
Prefer _ _ _ (RecordLit _) -> False
Expand All @@ -991,6 +999,7 @@ isNormalized e0 = loop (Syntax.denote e0)
case p of
Left s -> case r of
RecordLit _ -> False
Record _ -> False
Project _ _ -> False
Prefer _ _ _ (RecordLit _) -> False
_ -> not (null s) && Data.Set.toList (Data.Set.fromList s) == s
Expand Down
1 change: 1 addition & 0 deletions dhall/src/Dhall/Syntax.hs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import Dhall.Syntax.Instances.Foldable as Export ()
import Dhall.Syntax.Instances.Functor as Export ()
import Dhall.Syntax.Instances.Lift as Export ()
import Dhall.Syntax.Instances.Monad as Export ()
import Dhall.Syntax.Instances.Monoid as Export ()
import Dhall.Syntax.Instances.NFData as Export ()
import Dhall.Syntax.Instances.Ord as Export ()
import Dhall.Syntax.Instances.Pretty as Export
Expand Down
12 changes: 12 additions & 0 deletions dhall/src/Dhall/Syntax/Instances/Monoid.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{-# OPTIONS_GHC -Wno-orphans #-}

module Dhall.Syntax.Instances.Monoid () where

import Dhall.Syntax.Const (Const(..))
import Dhall.Syntax.Instances.Ord ()

instance Semigroup Const where
(<>) = max

instance Monoid Const where
mempty = Type
61 changes: 41 additions & 20 deletions dhall/src/Dhall/TypeCheck.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1158,22 +1158,26 @@ infer typer = loop
case Dhall.Map.lookup x xTs' of
Just _T' -> return _T'
Nothing -> die (MissingField x _E'')
_ -> do
let e' = eval values e

let e'' = quote names e'

case e' of
VUnion xTs' ->
case Dhall.Map.lookup x xTs' of
Just (Just _T') -> return (VHPi x _T' (\_ -> e'))
Just Nothing -> return e'
Nothing -> die (MissingConstructor x e)

_ -> do
let text = Dhall.Pretty.Internal.docToStrictText (Dhall.Pretty.Internal.prettyLabel x)

die (CantAccess text e'' _E'')
_ | VRecord xTs' <- eval values e ->
case Dhall.Map.lookup x xTs' of
Just _T' -> loop ctx (quote names _T')
Nothing -> die (MissingField x _E'')
| otherwise -> do
let e' = eval values e

let e'' = quote names e'

case e' of
VUnion xTs' ->
case Dhall.Map.lookup x xTs' of
Just (Just _T') -> return (VHPi x _T' (\_ -> e'))
Just Nothing -> return e'
Nothing -> die (MissingConstructor x e)

_ -> do
let text = Dhall.Pretty.Internal.docToStrictText (Dhall.Pretty.Internal.prettyLabel x)

die (CantAccess text e'' _E'')
Project e (Left xs) -> do
case duplicateElement xs of
Just x -> do
Expand All @@ -1185,6 +1189,9 @@ infer typer = loop

let _E'' = quote names _E'

let text =
Dhall.Pretty.Internal.docToStrictText (Dhall.Pretty.Internal.prettyLabels xs)

case _E' of
VRecord xTs' -> do
let process x =
Expand All @@ -1196,11 +1203,25 @@ infer typer = loop

fmap adapt (traverse process xs)

_ -> do
let text =
Dhall.Pretty.Internal.docToStrictText (Dhall.Pretty.Internal.prettyLabels xs)
_ | VRecord xTs' <- eval values e -> do
let process x =
case Dhall.Map.lookup x xTs' of
Just _T' -> do
_T'' <- loop ctx (quote names _T')

case _T'' of
VConst c -> pure c
_ -> die (CantProject text e _E'')

Nothing -> do
die (MissingField x _E'')

cs <- traverse process xs

return (VConst (mconcat cs))

die (CantProject text e _E'')
| otherwise -> do
die (CantProject text e _E'')

Project e (Right s) -> do
_E' <- loop ctx e
Expand Down
Loading