summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabrielGonzalez <>2019-07-29 05:29:00 (GMT)
committerhdiff <hdiff@hdiff.luite.com>2019-07-29 05:29:00 (GMT)
commite1b47b5bfe59b4d9169f4563c367fef445ef1428 (patch)
treef1065ad829323b2a6709ba796f500275ea4803e9
parent0a823f9465878aa72c1dd3543ca293df7b0388a2 (diff)
version 1.25.01.25.0
-rw-r--r--CHANGELOG.md115
-rw-r--r--benchmark/deep-nested-large-record/Main.hs16
-rw-r--r--benchmark/deep-nested-large-record/prelude.dhall4
-rw-r--r--benchmark/dhall-command/Main.hs20
-rw-r--r--benchmark/map/Main.hs44
-rw-r--r--benchmark/parser/Main.hs16
-rw-r--r--dhall-lang/Prelude/JSON/Tagged12
-rw-r--r--dhall-lang/Prelude/JSON/package.dhall21
-rw-r--r--dhall-lang/Prelude/Text/package.dhall8
-rw-r--r--dhall-lang/Prelude/package.dhall10
-rw-r--r--dhall-lang/tests/binary-decode/failure/unit/ApplyNoArgs.dhallbbin0 -> 6 bytes
-rw-r--r--dhall-lang/tests/binary-decode/failure/unit/LambdaExplicitlyNamedUnderscore.dhallbbin0 -> 6 bytes
-rw-r--r--dhall-lang/tests/binary-decode/failure/unit/ListOneWithAnnotation.dhallbbin0 -> 4 bytes
-rw-r--r--dhall-lang/tests/binary-decode/failure/unit/NaturalNegativeOne.dhallb1
-rw-r--r--dhall-lang/tests/binary-decode/failure/unit/OperatorOrTooFewArgs.dhallbbin0 -> 4 bytes
-rw-r--r--dhall-lang/tests/binary-decode/failure/unit/OperatorOrTooManyArgs.dhallbbin0 -> 6 bytes
-rw-r--r--dhall-lang/tests/binary-decode/failure/unit/OperatorUnknownOpcode.dhallbbin0 -> 5 bytes
-rw-r--r--dhall-lang/tests/binary-decode/failure/unit/PiExplicitlyNamedUnderscore.dhallbbin0 -> 6 bytes
-rw-r--r--dhall-lang/tests/binary-decode/failure/unit/VariableExplicitlyNamedUnderscore.dhallbbin0 -> 4 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/AnnotationA.dhallb1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/AnnotationB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/ApplicationA.dhallbbin0 -> 16 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/ApplicationB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/ApplicationMultipleA.dhallbbin0 -> 18 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/ApplicationMultipleB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/BoolFalseA.dhallb1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/BoolFalseB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/BoolIfA.dhallbbin0 -> 11 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/BoolIfB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/BoolTrueA.dhallb1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/BoolTrueB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/BuiltinNaturalShowA.dhallb1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/BuiltinNaturalShowB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/DoubleDoubleA.dhallbbin0 -> 9 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/DoubleDoubleB.dhall6
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/DoubleHalfA.dhallbbin0 -> 3 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/DoubleHalfB.dhall7
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/DoubleInfinityA.dhallbbin0 -> 3 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/DoubleInfinityB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/DoubleNegativeInfinityA.dhallbbin0 -> 3 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/DoubleNegativeInfinityB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/DoubleSingleA.dhallbbin0 -> 5 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/DoubleSingleB.dhall4
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/IntegerNegativeOneA.dhallb1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/IntegerNegativeOneB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/IntegerZeroA.dhallbbin0 -> 3 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/IntegerZeroB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/LambdaNamedXA.dhallbbin0 -> 9 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/LambdaNamedXB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/LambdaUnderscoreA.dhallbbin0 -> 11 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/LambdaUnderscoreB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/LetMultipleA.dhallbbin0 -> 26 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/LetMultipleB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/LetOneTypedA.dhallbbin0 -> 20 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/LetOneTypedB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/LetOneUntypedA.dhallbbin0 -> 13 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/LetOneUntypedB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/ListEmptyA.dhallb1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/ListEmptyB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/ListOneA.dhallbbin0 -> 4 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/ListOneB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/MergeAnnotatedA.dhallbbin0 -> 5 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/MergeAnnotatedB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/MergeUnannotatedA.dhallbbin0 -> 4 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/MergeUnannotatedB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/NaturalTwentyFourA.dhallb1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/NaturalTwentyFourB.dhall5
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/NaturalZeroA.dhallbbin0 -> 3 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/NaturalZeroB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/OperatorAndA.dhallbbin0 -> 5 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/OperatorAndB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/OperatorCombineA.dhallbbin0 -> 5 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/OperatorCombineB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/OperatorCombineTypesA.dhallbbin0 -> 5 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/OperatorCombineTypesB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/OperatorEqA.dhallbbin0 -> 5 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/OperatorEqB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/OperatorImportAltA.dhallbbin0 -> 5 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/OperatorImportAltB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/OperatorListAppendA.dhallbbin0 -> 5 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/OperatorListAppendB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/OperatorNeqA.dhallbbin0 -> 5 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/OperatorNeqB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/OperatorOrA.dhallbbin0 -> 5 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/OperatorOrB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/OperatorPlusA.dhallbbin0 -> 5 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/OperatorPlusB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/OperatorPreferA.dhallbbin0 -> 5 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/OperatorPreferB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/OperatorTextAppendA.dhallbbin0 -> 5 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/OperatorTextAppendB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/OperatorTimesA.dhallbbin0 -> 5 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/OperatorTimesB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/PiNamedXA.dhallbbin0 -> 13 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/PiNamedXB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/PiUnderscoreA.dhallb1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/PiUnderscoreB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/RecordFieldAccessA.dhallbbin0 -> 5 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/RecordFieldAccessB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/RecordLiteralA.dhallb1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/RecordLiteralB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/RecordProjectFieldsA.dhallbbin0 -> 12 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/RecordProjectFieldsB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/RecordTypeA.dhallb1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/RecordTypeB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/SomeA.dhallbbin0 -> 4 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/SomeB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/TextInterpolatedA.dhallbbin0 -> 11 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/TextInterpolatedB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/TextSimpleA.dhallb1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/TextSimpleB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/UnionTypeA.dhallb1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/UnionTypeB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/VariableNamedA.dhallb1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/VariableNamedB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/VariableNamedOversizedIntA.dhallbbin0 -> 12 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/VariableNamedOversizedIntB.dhall16
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/VariableUnderscoreA.dhallb1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/VariableUnderscoreB.dhall1
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/VariableUnderscoreOversizedIntA.dhallbbin0 -> 9 bytes
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/VariableUnderscoreOversizedIntB.dhall13
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/recordProjectionByExpressionA.dhallb2
-rw-r--r--dhall-lang/tests/binary-decode/success/unit/recordProjectionByExpressionB.dhall1
-rw-r--r--dhall-lang/tests/import/cache/dhall/1220efc43103e49b56c5bf089db8e0365bbfc455b8a2f0dc6ee5727a3586f85969fdbin0 -> 49 bytes
-rw-r--r--dhall-lang/tests/import/data/simpleLocation.dhall1
-rw-r--r--dhall-lang/tests/import/success/asLocationA.dhall8
-rw-r--r--dhall-lang/tests/import/success/asLocationB.dhall8
-rw-r--r--dhall-lang/tests/import/success/customHeadersA.dhall2
-rw-r--r--dhall-lang/tests/import/success/hashFromCacheA.dhall11
-rw-r--r--dhall-lang/tests/import/success/hashFromCacheB.dhall3
-rw-r--r--dhall-lang/tests/import/success/headerForwardingA.dhall2
-rw-r--r--dhall-lang/tests/import/success/noHeaderForwardingA.dhall2
-rw-r--r--dhall-lang/tests/normalization/success/simple/equalNoCommuteA.dhall1
-rw-r--r--dhall-lang/tests/normalization/success/simple/equalNoCommuteB.dhall1
-rw-r--r--dhall-lang/tests/normalization/success/simple/notEqualNoCommuteA.dhall1
-rw-r--r--dhall-lang/tests/normalization/success/simple/notEqualNoCommuteB.dhall1
-rw-r--r--dhall-lang/tests/normalization/success/simple/plusNoCommuteA.dhall1
-rw-r--r--dhall-lang/tests/normalization/success/simple/plusNoCommuteB.dhall1
-rw-r--r--dhall-lang/tests/normalization/success/simple/timesNoCommuteA.dhall1
-rw-r--r--dhall-lang/tests/normalization/success/simple/timesNoCommuteB.dhall1
-rw-r--r--dhall-lang/tests/normalization/success/unit/EmptyToMapA.dhall1
-rw-r--r--dhall-lang/tests/normalization/success/unit/EmptyToMapB.dhall1
-rw-r--r--dhall-lang/tests/normalization/success/unit/ListNormalizeTypeAnnotationA.dhall2
-rw-r--r--dhall-lang/tests/normalization/success/unit/ListNormalizeTypeAnnotationB.dhall2
-rw-r--r--dhall-lang/tests/normalization/success/unit/NoneNaturalA.dhall1
-rw-r--r--dhall-lang/tests/normalization/success/unit/NoneNaturalB.dhall1
-rw-r--r--dhall-lang/tests/normalization/success/unit/RecordProjectionByTypeEmptyA.dhall (renamed from dhall-lang/tests/normalization/success/unit/RecordProjectionTypeEmptyA.dhall)0
-rw-r--r--dhall-lang/tests/normalization/success/unit/RecordProjectionByTypeEmptyB.dhall (renamed from dhall-lang/tests/normalization/success/unit/RecordProjectionTypeEmptyB.dhall)0
-rw-r--r--dhall-lang/tests/normalization/success/unit/RecordProjectionByTypeNonEmptyA.dhall (renamed from dhall-lang/tests/normalization/success/unit/RecordProjectionTypeNonEmptyA.dhall)0
-rw-r--r--dhall-lang/tests/normalization/success/unit/RecordProjectionByTypeNonEmptyB.dhall (renamed from dhall-lang/tests/normalization/success/unit/RecordProjectionTypeNonEmptyB.dhall)0
-rw-r--r--dhall-lang/tests/normalization/success/unit/RecordProjectionByTypeNormalizeProjectionA.dhall1
-rw-r--r--dhall-lang/tests/normalization/success/unit/RecordProjectionByTypeNormalizeProjectionB.dhall1
-rw-r--r--dhall-lang/tests/normalization/success/unit/RecordProjectionNormalizeFieldsA.dhall1
-rw-r--r--dhall-lang/tests/normalization/success/unit/RecordProjectionNormalizeFieldsB.dhall1
-rw-r--r--dhall-lang/tests/normalization/success/unit/ToMapA.dhall1
-rw-r--r--dhall-lang/tests/normalization/success/unit/ToMapB.dhall4
-rw-r--r--dhall-lang/tests/normalization/success/unit/ToMapWithTypeA.dhall16
-rw-r--r--dhall-lang/tests/normalization/success/unit/ToMapWithTypeB.dhall4
-rw-r--r--dhall-lang/tests/parser/failure/nonCharacter.dhall1
-rw-r--r--dhall-lang/tests/parser/failure/nonUtf8.dhall4
-rw-r--r--dhall-lang/tests/parser/failure/urlWithoutPath.dhall2
-rw-r--r--dhall-lang/tests/parser/success/annotationsA.dhall5
-rw-r--r--dhall-lang/tests/parser/success/annotationsB.dhallbbin167 -> 76 bytes
-rw-r--r--dhall-lang/tests/parser/success/recordProjectionByExpressionA.dhall (renamed from dhall-lang/tests/parser/success/RecordProjectionByType.dhall)0
-rw-r--r--dhall-lang/tests/parser/success/recordProjectionByExpressionB.dhallbbin0 -> 279 bytes
-rw-r--r--dhall-lang/tests/parser/success/text/escapedDoubleQuotedStringA.dhall2
-rw-r--r--dhall-lang/tests/parser/success/text/escapedDoubleQuotedStringB.dhallb4
-rw-r--r--dhall-lang/tests/parser/success/toMapA.dhall1
-rw-r--r--dhall-lang/tests/parser/success/toMapB.dhallb1
-rw-r--r--dhall-lang/tests/parser/success/unit/ListLitEmpty1A.dhall (renamed from dhall-lang/tests/parser/success/unit/ListLitEmptyA.dhall)0
-rw-r--r--dhall-lang/tests/parser/success/unit/ListLitEmpty1B.dhallb (renamed from dhall-lang/tests/parser/success/unit/ListLitEmptyB.dhallb)bin6 -> 6 bytes
-rw-r--r--dhall-lang/tests/parser/success/unit/ListLitEmpty2A.dhall1
-rw-r--r--dhall-lang/tests/parser/success/unit/ListLitEmpty2B.dhallbbin0 -> 7 bytes
-rw-r--r--dhall-lang/tests/parser/success/unit/ListLitEmptyPrecedenceA.dhall1
-rw-r--r--dhall-lang/tests/parser/success/unit/ListLitEmptyPrecedenceB.dhallbbin0 -> 18 bytes
-rw-r--r--dhall-lang/tests/parser/success/unit/RecordFieldAccessA.dhall1
-rw-r--r--dhall-lang/tests/parser/success/unit/RecordFieldAccessB.dhallbbin0 -> 8 bytes
-rw-r--r--dhall-lang/tests/parser/success/unit/RecordProjectFieldsA.dhall1
-rw-r--r--dhall-lang/tests/parser/success/unit/RecordProjectFieldsB.dhallbbin0 -> 12 bytes
-rw-r--r--dhall-lang/tests/parser/success/unit/RecordProjectionByTypeA.dhall1
-rw-r--r--dhall-lang/tests/parser/success/unit/RecordProjectionByTypeB.dhallb2
-rw-r--r--dhall-lang/tests/parser/success/unit/RecordProjectionByTypeEmptyA.dhall1
-rw-r--r--dhall-lang/tests/parser/success/unit/RecordProjectionByTypeEmptyB.dhallb2
-rw-r--r--dhall-lang/tests/parser/success/unit/import/asLocationA.dhall6
-rw-r--r--dhall-lang/tests/parser/success/unit/import/asLocationB.dhallb2
-rw-r--r--dhall-lang/tests/parser/success/unit/import/inlineUsingA.dhall4
-rw-r--r--dhall-lang/tests/parser/success/unit/import/inlineUsingB.dhallbbin108 -> 111 bytes
-rw-r--r--dhall-lang/tests/parser/success/unit/import/parenthesizeUsingB.dhallbbin241 -> 194 bytes
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/basicHttpA.dhall1
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/basicHttpB.dhallbbin0 -> 35 bytes
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/basicHttpsA.dhall1
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/basicHttpsB.dhallbbin0 -> 116 bytes
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/emptyPath0A.dhall3
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/emptyPath0B.dhallbbin0 -> 21 bytes
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/emptyPath1A.dhall1
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/emptyPath1B.dhallbbin0 -> 21 bytes
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/emptyPathSegmentA.dhall2
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/emptyPathSegmentB.dhallbbin0 -> 29 bytes
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/emptyQueryA.dhall3
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/emptyQueryB.dhallbbin0 -> 24 bytes
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/escapedPathA.dhall1
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/escapedPathB.dhallbbin0 -> 32 bytes
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/escapedQueryA.dhall2
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/escapedQueryB.dhallbbin0 -> 41 bytes
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/fragmentParsesAsListAppendA.dhall11
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/fragmentParsesAsListAppendB.dhallbbin0 -> 33 bytes
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/ipv4A.dhall1
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/ipv4B.dhallbbin0 -> 30 bytes
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/ipv6longA.dhall1
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/ipv6longB.dhallbbin0 -> 58 bytes
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/ipv6mediumA.dhall1
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/ipv6mediumB.dhallbbin0 -> 55 bytes
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/ipv6shortA.dhall1
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/ipv6shortB.dhallbbin0 -> 25 bytes
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/ipv6withipv4A.dhall1
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/ipv6withipv4B.dhallbbin0 -> 59 bytes
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/portA.dhall1
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/portB.dhallbbin0 -> 29 bytes
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/potPourriA.dhall1
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/potPourriB.dhallbbin0 -> 75 bytes
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/quotedPathFakeUrlEncodeA.dhall1
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/quotedPathFakeUrlEncodeB.dhallbbin0 -> 28 bytes
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/userinfoA.dhall1
-rw-r--r--dhall-lang/tests/parser/success/unit/import/urls/userinfoB.dhallbbin0 -> 33 bytes
-rw-r--r--dhall-lang/tests/semantic-hash/success/haskell-tutorial/access/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/haskell-tutorial/access/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/haskell-tutorial/access/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/haskell-tutorial/access/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/haskell-tutorial/combineTypes/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/haskell-tutorial/combineTypes/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/haskell-tutorial/combineTypes/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/haskell-tutorial/combineTypes/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/haskell-tutorial/prefer/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/haskell-tutorial/prefer/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/haskell-tutorial/projection/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/haskell-tutorial/projection/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/and/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/and/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/and/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/and/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/build/0A.dhall2
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/build/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/build/1A.dhall2
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/build/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/even/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/even/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/even/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/even/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/even/2A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/even/2B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/even/3A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/even/3B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/fold/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/fold/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/fold/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/fold/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/not/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/not/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/not/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/not/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/2A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/2B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/3A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/3B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/or/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/or/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/or/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/or/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/show/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/show/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/show/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Bool/show/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Double/show/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Double/show/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Double/show/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Double/show/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Integer/show/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Integer/show/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Integer/show/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Integer/show/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Integer/toDouble/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Integer/toDouble/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Integer/toDouble/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Integer/toDouble/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/all/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/all/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/all/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/all/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/any/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/any/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/any/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/any/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/build/0A.dhall7
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/build/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/build/1A.dhall7
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/build/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/concat/0A.dhall5
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/concat/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/concat/1A.dhall5
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/concat/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/concatMap/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/concatMap/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/concatMap/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/concatMap/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/filter/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/filter/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/filter/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/filter/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/fold/0A.dhall6
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/fold/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/fold/1A.dhall7
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/fold/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/fold/2A.dhall4
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/fold/2B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/generate/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/generate/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/generate/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/generate/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/head/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/head/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/head/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/head/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/indexed/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/indexed/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/indexed/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/indexed/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/iterate/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/iterate/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/iterate/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/iterate/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/last/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/last/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/last/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/last/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/length/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/length/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/length/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/length/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/map/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/map/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/map/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/map/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/null/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/null/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/null/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/null/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/replicate/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/replicate/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/replicate/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/replicate/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/reverse/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/reverse/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/reverse/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/reverse/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/shifted/0A.dhall15
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/shifted/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/shifted/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/shifted/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/unzip/0A.dhall7
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/unzip/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/unzip/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/List/unzip/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/build/0A.dhall6
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/build/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/build/1A.dhall6
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/build/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/enumerate/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/enumerate/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/enumerate/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/enumerate/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/even/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/even/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/even/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/even/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/2A.dhall4
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/2B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/isZero/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/isZero/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/isZero/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/isZero/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/odd/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/odd/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/odd/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/odd/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/product/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/product/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/product/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/product/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/show/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/show/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/show/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/show/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/sum/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/sum/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/sum/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/sum/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/toDouble/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/toDouble/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/toDouble/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/toDouble/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/toInteger/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/toInteger/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/toInteger/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Natural/toInteger/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/all/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/all/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/all/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/all/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/any/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/any/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/any/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/any/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/build/0A.dhall7
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/build/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/build/1A.dhall7
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/build/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/2A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/2B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/filter/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/filter/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/filter/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/filter/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/fold/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/fold/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/fold/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/fold/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/head/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/head/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/head/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/head/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/head/2A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/head/2B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/last/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/last/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/last/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/last/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/last/2A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/last/2B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/length/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/length/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/length/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/length/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/map/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/map/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/map/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/map/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/null/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/null/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/null/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/null/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/toList/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/toList/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/toList/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/toList/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/unzip/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/unzip/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/unzip/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Optional/unzip/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Text/concat/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Text/concat/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Text/concat/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Text/concat/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Text/concatMap/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Text/concatMap/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Text/concatMap/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Text/concatMap/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Text/concatMapSep/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Text/concatMapSep/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Text/concatMapSep/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Text/concatMapSep/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Text/concatSep/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Text/concatSep/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Text/concatSep/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Text/concatSep/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Text/show/0A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Text/show/0B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Text/show/1A.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/prelude/Text/show/1B.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/remoteSystemsA.dhall52
-rw-r--r--dhall-lang/tests/semantic-hash/success/remoteSystemsB.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/doubleShowA.dhall6
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/doubleShowB.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/enumA.dhall8
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/enumB.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/integerShowA.dhall4
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/integerShowB.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/integerToDoubleA.dhall10
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/integerToDoubleB.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/letletA.dhall3
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/letletB.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/listBuildA.dhall22
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/listBuildB.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/multiLineA.dhall4
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/multiLineB.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/naturalBuildA.dhall18
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/naturalBuildB.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/naturalPlusA.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/naturalPlusB.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/naturalShowA.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/naturalShowB.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/naturalToIntegerA.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/naturalToIntegerB.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/optionalBuildA.dhall32
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/optionalBuildB.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/optionalBuildFoldA.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/optionalBuildFoldB.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/optionalFoldA.dhall7
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/optionalFoldB.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/sortOperatorA.dhall1
-rw-r--r--dhall-lang/tests/semantic-hash/success/simple/sortOperatorB.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/simplifications/andA.dhall6
-rw-r--r--dhall-lang/tests/semantic-hash/success/simplifications/andB.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/simplifications/eqA.dhall4
-rw-r--r--dhall-lang/tests/semantic-hash/success/simplifications/eqB.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/simplifications/ifThenElseA.dhall3
-rw-r--r--dhall-lang/tests/semantic-hash/success/simplifications/ifThenElseB.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/simplifications/neA.dhall4
-rw-r--r--dhall-lang/tests/semantic-hash/success/simplifications/neB.hash1
-rw-r--r--dhall-lang/tests/semantic-hash/success/simplifications/orA.dhall6
-rw-r--r--dhall-lang/tests/semantic-hash/success/simplifications/orB.hash1
-rw-r--r--dhall-lang/tests/type-inference/success/simple/alternativesAreTypesA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/simple/alternativesAreTypesB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/simple/kindParameterA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/simple/kindParameterB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/BoolA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/BoolB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/DoubleA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/DoubleB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/DoubleLiteralA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/DoubleLiteralB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/DoubleShowA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/DoubleShowB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/FalseA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/FalseB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/FunctionA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/FunctionApplicationA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/FunctionApplicationB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/FunctionB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/FunctionNamedArgA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/FunctionNamedArgB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/FunctionTypeKindKindA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/FunctionTypeKindKindB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/FunctionTypeKindTermA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/FunctionTypeKindTermB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/FunctionTypeKindTypeA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/FunctionTypeKindTypeB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/FunctionTypeTermTermA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/FunctionTypeTermTermB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/FunctionTypeTypeTermA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/FunctionTypeTypeTermB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/FunctionTypeTypeTypeA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/FunctionTypeTypeTypeB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/FunctionTypeUsingArgumentA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/FunctionTypeUsingArgumentB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/IfA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/IfB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/IfNormalizeArgumentsA.dhall9
-rw-r--r--dhall-lang/tests/type-inference/success/unit/IfNormalizeArgumentsB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/IntegerA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/IntegerB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/IntegerLiteralA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/IntegerLiteralB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/IntegerShowA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/IntegerShowB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/IntegerToDoubleA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/IntegerToDoubleB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/KindA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/KindB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/LetA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/LetB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/LetNestedTypeSynonymA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/LetNestedTypeSynonymB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/LetTypeSynonymA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/LetTypeSynonymB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/LetWithAnnotationA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/LetWithAnnotationB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/ListA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/ListB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/ListBuildA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/ListBuildB.dhall3
-rw-r--r--dhall-lang/tests/type-inference/success/unit/ListFoldA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/ListFoldB.dhall6
-rw-r--r--dhall-lang/tests/type-inference/success/unit/ListHeadA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/ListHeadB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/ListIndexedA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/ListIndexedB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/ListLastA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/ListLastB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/ListLengthA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/ListLengthB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/ListLiteralEmptyA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/ListLiteralEmptyB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/ListLiteralEmptyNormalizeAnnotationA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/ListLiteralEmptyNormalizeAnnotationB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/ListLiteralNormalizeArgumentsA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/ListLiteralNormalizeArgumentsB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/ListLiteralOneA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/ListLiteralOneB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/ListReverseA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/ListReverseB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/MergeEmptyUnionA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/MergeEmptyUnionB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/MergeOneA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/MergeOneB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/MergeOneEmptyA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/MergeOneEmptyB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/MergeOneWithAnnotationA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/MergeOneWithAnnotationB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/NaturalA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/NaturalB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/NaturalBuildA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/NaturalBuildB.dhall6
-rw-r--r--dhall-lang/tests/type-inference/success/unit/NaturalEvenA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/NaturalEvenB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/NaturalFoldA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/NaturalFoldB.dhall5
-rw-r--r--dhall-lang/tests/type-inference/success/unit/NaturalIsZeroA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/NaturalIsZeroB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/NaturalLiteralA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/NaturalLiteralB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/NaturalOddA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/NaturalOddB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/NaturalShowA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/NaturalShowB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/NaturalToIntegerA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/NaturalToIntegerB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/NoneA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/NoneB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorAndA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorAndB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorAndNormalizeArgumentsA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorAndNormalizeArgumentsB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorEqualA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorEqualB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorEqualNormalizeArgumentsA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorEqualNormalizeArgumentsB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorListConcatenateA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorListConcatenateB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorListConcatenateNormalizeArgumentsA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorListConcatenateNormalizeArgumentsB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorNotEqualA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorNotEqualB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorNotEqualNormalizeArgumentsA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorNotEqualNormalizeArgumentsB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorOrA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorOrB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorOrNormalizeArgumentsA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorOrNormalizeArgumentsB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorPlusA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorPlusB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorPlusNormalizeArgumentsA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorPlusNormalizeArgumentsB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorTextConcatenateA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorTextConcatenateB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorTextConcatenateNormalizeArgumentsA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorTextConcatenateNormalizeArgumentsB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorTimesA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorTimesB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorTimesNormalizeArgumentsA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OperatorTimesNormalizeArgumentsB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OptionalA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OptionalB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OptionalBuildA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OptionalBuildB.dhall7
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OptionalFoldA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/OptionalFoldB.dhall6
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordEmptyA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordEmptyB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordNestedKindA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordNestedKindB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordNestedKindLikeA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordNestedKindLikeB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordNestedTypeA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordNestedTypeB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordNestedTypeLikeA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordNestedTypeLikeB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordOneKindA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordOneKindB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordOneTypeA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordOneTypeB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordOneValueA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordOneValueB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordProjectionByTypeA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordProjectionByTypeB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordProjectionByTypeEmptyA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordProjectionByTypeEmptyB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordProjectionByTypeJudgmentalEqualityA.dhall5
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordProjectionByTypeJudgmentalEqualityB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordProjectionEmptyA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordProjectionEmptyB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordProjectionKindA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordProjectionKindB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordProjectionTypeA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordProjectionTypeB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordProjectionValueA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordProjectionValueB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordSelectionKindA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordSelectionKindB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordSelectionTypeA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordSelectionTypeB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordSelectionValueA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordSelectionValueB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordTypeA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordTypeB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordTypeEmptyA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordTypeEmptyB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordTypeKindA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordTypeKindB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordTypeKindLikeA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordTypeKindLikeB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordTypeNestedKindA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordTypeNestedKindB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordTypeNestedKindLikeA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordTypeNestedKindLikeB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordTypeTypeA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecordTypeTypeB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeLhsEmptyA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeLhsEmptyB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRecursivelyA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRecursivelyB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRecursivelyKindsA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRecursivelyKindsB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRecursivelyTypesA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRecursivelyTypesB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRhsEmptyA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRhsEmptyB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeTwoA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeTwoB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeTwoKindsA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeTwoKindsB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeTwoTypesA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeTwoTypesB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRecursivelyA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRecursivelyB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRecursivelyKindsA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRecursivelyKindsB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRecursivelyTypesA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRecursivelyTypesB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRhsEmptyA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRhsEmptyB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeTwoA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeTwoB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeTwoKindsA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeTwoKindsB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeTwoTypesA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeTwoTypesB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeRhsEmptyA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeRhsEmptyB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoDifferentA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoDifferentB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoKindsA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoKindsB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoTypesA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoTypesB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/SomeTrueA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/SomeTrueB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/TextA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/TextB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/TextLiteralA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/TextLiteralB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/TextLiteralNormalizeArgumentsA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/TextLiteralNormalizeArgumentsB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/TextLiteralWithInterpolationA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/TextLiteralWithInterpolationB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/TextShowA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/TextShowB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/ToMapA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/ToMapB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/TrueA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/TrueB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/TypeA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/TypeAnnotationA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/TypeAnnotationB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/TypeAnnotationSortA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/TypeAnnotationSortB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/TypeB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/UnionConstructorEmptyFieldA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/UnionConstructorEmptyFieldB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/UnionConstructorFieldA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/UnionConstructorFieldB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/UnionLiteralOneA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/UnionLiteralOneB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/UnionTypeEmptyA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/UnionTypeEmptyB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/UnionTypeKindA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/UnionTypeKindB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/UnionTypeOneA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/UnionTypeOneB.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/UnionTypeTypeA.dhall1
-rw-r--r--dhall-lang/tests/type-inference/success/unit/UnionTypeTypeB.dhall1
-rw-r--r--dhall-lang/tests/typecheck/failure/customHeadersUsingBoundVariable.dhall2
-rw-r--r--dhall.cabal190
-rw-r--r--src/Dhall.hs218
-rw-r--r--src/Dhall/Binary.hs101
-rw-r--r--src/Dhall/Context.hs2
-rw-r--r--src/Dhall/Core.hs241
-rw-r--r--src/Dhall/Diff.hs61
-rw-r--r--src/Dhall/Eval.hs48
-rw-r--r--src/Dhall/Freeze.hs10
-rw-r--r--src/Dhall/Import.hs708
-rw-r--r--src/Dhall/Import/HTTP.hs52
-rw-r--r--src/Dhall/Import/Types.hs107
-rw-r--r--src/Dhall/Lint.hs50
-rw-r--r--src/Dhall/Main.hs77
-rw-r--r--src/Dhall/Map.hs330
-rw-r--r--src/Dhall/Parser/Combinators.hs22
-rw-r--r--src/Dhall/Parser/Expression.hs122
-rw-r--r--src/Dhall/Parser/Token.hs67
-rw-r--r--src/Dhall/Pretty/Internal.hs44
-rw-r--r--src/Dhall/Set.hs43
-rw-r--r--src/Dhall/Src.hs22
-rw-r--r--src/Dhall/Tutorial.hs8
-rw-r--r--src/Dhall/TypeCheck.hs593
-rw-r--r--src/Dhall/X.hs28
-rw-r--r--tests/Dhall/Test/Dhall.hs3
-rw-r--r--tests/Dhall/Test/Diff.hs63
-rw-r--r--tests/Dhall/Test/Import.hs23
-rw-r--r--tests/Dhall/Test/Main.hs12
-rw-r--r--tests/Dhall/Test/Normalization.hs6
-rw-r--r--tests/Dhall/Test/Parser.hs65
-rw-r--r--tests/Dhall/Test/QuickCheck.hs131
-rw-r--r--tests/Dhall/Test/Regression.hs30
-rw-r--r--tests/Dhall/Test/SemanticHash.hs49
-rw-r--r--tests/Dhall/Test/TypeCheck.hs9
-rw-r--r--tests/Dhall/Test/TypeInference.hs49
-rw-r--r--tests/Dhall/Test/Util.hs102
-rw-r--r--tests/diff/appList.txt4
-rw-r--r--tests/diff/appListA.dhall1
-rw-r--r--tests/diff/appListB.dhall1
-rw-r--r--tests/format/escapeSingleQuotedOpenInterpolationB.dhall4
-rw-r--r--tests/format/innerMultilineA.dhall11
-rw-r--r--tests/format/innerMultilineB.dhall1
-rw-r--r--tests/format/multilineB.dhall4
-rw-r--r--tests/format/unicodeA.dhall8
-rw-r--r--tests/format/unicodeB.dhall8
-rw-r--r--tests/regression/issue151a.dhall2
-rw-r--r--tests/regression/issue151b.dhall2
851 files changed, 3693 insertions, 1452 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index dd78d9d..e037d28 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,118 @@
+1.25.0
+
+* Supports version 8.0.0 of the standard
+ * See: https://github.com/dhall-lang/dhall-lang/releases/tag/v8.0.0
+* BREAKING CHANGE: Remove support for old-style `List`-like `Optional` literals
+ * List-like `Optional` Literals (i.e. `[ 1 ] : Optional Natural`) are no
+ longer valid
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1002
+* BREAKING CHANGE: Add support for semi-semantic caching
+ * This change significantly improves the performance of imports
+ * This change also automatically caches imports without an integrity check
+ * This changes several types in `Dhall.Import` to support this new
+ feature
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1113
+* BREAKING CHANGE: Implement new Unicode braced escape sequence
+ * Escape sequences encoding surrogate pairs are no longer valid
+ * Instead, characters previously encoded as surrogate pairs can instead be
+ encoded as a braced sequence
+ * For example: "\uD834\uDD1E" must now be written as "\u{1D11E}"
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/987
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1104
+* BREAKING CHANGE: Make the type of extract richer:
+ * `Dhall.extract` can now return a detailed error instead of just a `Maybe`
+ * This is a breaking chnage because the type of `extract` changed
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1011
+* BREAKING CHANGE: Add support for importing expressions `as Location`
+ * This is a breaking change because a new `Location` constructor was added
+ to `ImportMode`
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1019
+* BREAKING CHANGE: Switch `Var` to use an `Int`
+ * This is a performance improvement, but also a breaking change since the
+ `Integer` in the `Var` constructor was changed to an `Int`
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1044
+* BREAKING CHANGE: Add new `toMap` keyword
+ * This is a breaking change to the API because a new `ToMap` constructor
+ was added to the `Expr` type
+ * This is also a technically breaking change to the language because `toMap`
+ is now a reserved keyword, although most code should be unaffected in
+ practice
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1041
+* BREAKING CHANGE: Sort the fields of a record projection during normalization
+ * This is a technically breaking change to the language because any
+ expressions with an uninterpreted record projection will have a different
+ semantic integrity check. However, most could should be unaffected in
+ practice
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1111
+* BUG FIX: Fix substitution into record projection by type
+ * An expression like this one was being incorrectly rejected:
+ `let e = { a = 10, b = "Text" } let s = { a : Natural } in e.(s)`, which
+ this change fixes
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1012
+* BUG FIX: Reject record projection when there is a field type mismatch
+ * Record projection by type was previously not checking the expected
+ field types, which this change fixes
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1027
+* BUG FIX: Fix linting of unused let bindings
+ * Certain let bindings were not correctly detected as unused, which this
+ change fixes
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1001
+* BUG FIX: Fix `--file` option
+ * The `--file` option from the previous release did not work, due to not
+ computing relative paths correctly, which this change fixes
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1004
+* BUG FIX: Minor fix to `dhall diff`
+ * `dhall diff` was incorrectly displaying spurious differences for
+ identical lists that were function arguments, which this change fixes
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1006
+* BUG FIX: Allow `Sort` as type annotation
+ * This should have been implemented in the previous release as part of
+ supporting version 8.0.0 of the standard, but was missed
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1024
+* BUG FIX: `Dhall.Map`: Reflect original key ordering in `Ord` instance
+ * `Dhall.Map` now considers key order when comparing `Map`s, which it should
+ have done before, but didn't
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1050
+* BUG FIX: Consistently format multi-line strings
+ * The formatter now formats naked multi-line strings the same as nested
+ multi-line strings
+ * Specifically, naked multi-line strings can now be formatted on a single
+ (just like nested multi-line strings)
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1056
+* BUG FIX: Make `isNormalized` consistent with `normalize`
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1115
+* BUG FIX: Make `normalizeWithM` consistent with `normalize`
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1126
+* BUG FIX: Fix import alternatives to recover from type errors
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1152
+* Feature: Semi-semantic caching
+ * The Haskell implementation now implicitly caches *all* local imports, not
+ just imports frozen by integrity checks, so that you don't have to freeze
+ them when doing local development
+ * These cached imports are still correctly invalidated if they or any of
+ their dependencies change
+ * This new implicit cache is stored underneath `~/.cache/dhall-haskell` by
+ default
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1154
+* Feature: New `dhall text` subcommand
+ * This new subcommand supersedes the old `dhall-to-text` executable
+* Feature: Add `instance Lift (Expr s a)`
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1119
+* Fixes and improvements to error messages:
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1030
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1137
+* Fixes and improvements to tests:
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1155
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1159
+* Performance improvements
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1036
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1051
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1048
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1057
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1065
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1066
+ * See: https://github.com/dhall-lang/dhall-haskell/pull/1085
+
1.24.0
* Supports version 8.0.0 of the standard
diff --git a/benchmark/deep-nested-large-record/Main.hs b/benchmark/deep-nested-large-record/Main.hs
index 7e1b9fb..0d153d4 100644
--- a/benchmark/deep-nested-large-record/Main.hs
+++ b/benchmark/deep-nested-large-record/Main.hs
@@ -1,13 +1,13 @@
{-# LANGUAGE OverloadedStrings #-}
module Main (main) where
-import Criterion.Main (defaultMain)
+import Gauge(defaultMain)
-import qualified Criterion as Criterion
import qualified Data.Sequence as Seq
import qualified Dhall.Core as Core
import qualified Dhall.Import as Import
import qualified Dhall.TypeCheck as TypeCheck
+import qualified Gauge
dhallPreludeImport :: Core.Import
dhallPreludeImport = Core.Import
@@ -21,8 +21,8 @@ dhallPreludeImport = Core.Import
}
}
-issue412 :: Core.Expr s TypeCheck.X -> Criterion.Benchmarkable
-issue412 prelude = Criterion.whnf TypeCheck.typeOf expr
+issue412 :: Core.Expr s TypeCheck.X -> Gauge.Benchmarkable
+issue412 prelude = Gauge.whnf TypeCheck.typeOf expr
where
expr
= Core.Let (pure (Core.Binding "prelude" Nothing prelude))
@@ -30,8 +30,8 @@ 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
+unionPerformance :: Core.Expr s TypeCheck.X -> Gauge.Benchmarkable
+unionPerformance prelude = Gauge.whnf TypeCheck.typeOf expr
where
innerBinding =
Core.Binding "big" Nothing
@@ -47,6 +47,6 @@ main :: IO ()
main = do
prelude <- Import.load (Core.Embed dhallPreludeImport)
defaultMain
- [ Criterion.bench "issue 412" (issue412 prelude)
- , Criterion.bench "union performance" (unionPerformance prelude)
+ [ Gauge.bench "issue 412" (issue412 prelude)
+ , Gauge.bench "union performance" (unionPerformance prelude)
]
diff --git a/benchmark/deep-nested-large-record/prelude.dhall b/benchmark/deep-nested-large-record/prelude.dhall
index 94d1063..bbb315b 100644
--- a/benchmark/deep-nested-large-record/prelude.dhall
+++ b/benchmark/deep-nested-large-record/prelude.dhall
@@ -1,5 +1,5 @@
{ types =
- { Big = constructors ./BigEnum.dhall
- , Little = constructors ./LittleEnum.dhall
+ { Big = ./BigEnum.dhall
+ , Little = ./LittleEnum.dhall
}
}
diff --git a/benchmark/dhall-command/Main.hs b/benchmark/dhall-command/Main.hs
deleted file mode 100644
index 311c8b1..0000000
--- a/benchmark/dhall-command/Main.hs
+++ /dev/null
@@ -1,20 +0,0 @@
-
-{-# LANGUAGE OverloadedStrings #-}
-
-module Main where
-
-import qualified Dhall.Main as Main
-import Dhall.Binary (defaultStandardVersion)
-
-options :: Main.Options
-options = Main.Options
- { Main.mode = Main.Default Nothing False False
- , Main.explain = False
- , Main.plain = False
- , Main.ascii = False
- , Main.standardVersion = defaultStandardVersion
- }
-
-main :: IO ()
-main = do
- Main.command options
diff --git a/benchmark/map/Main.hs b/benchmark/map/Main.hs
deleted file mode 100644
index a36dbc4..0000000
--- a/benchmark/map/Main.hs
+++ /dev/null
@@ -1,44 +0,0 @@
-{-# LANGUAGE BangPatterns #-}
-{-# LANGUAGE TypeApplications #-}
-
-module Main where
-
-import Criterion.Main (defaultMain, bgroup, bench, whnf, nfIO)
-
-import qualified Criterion.Main as Criterion
-import qualified Dhall.Map as Map
-
-testData :: Integer -> Map.Map Integer Integer
-testData i = foldr (\j -> Map.insert j j) mempty [1 .. i]
-
-benchOrderedTraversal :: String -> Map.Map Integer Integer -> Criterion.Benchmark
-benchOrderedTraversal dataLabel mapData =
- bgroup ("Ordered Traversals: " <> dataLabel)
- [ bench "traverseWithKey" $
- whnf (Map.traverseWithKey (\_ i -> pure @Maybe $ i ^ i)) mapData
- , bench "traverseWithKey_" $
- whnf (Map.traverseWithKey_ (\_ i -> pure @Maybe (i ^ i) *> pure ())) mapData
- ]
-
-benchUnorderedTraversal :: String -> Map.Map Integer Integer -> Criterion.Benchmark
-benchUnorderedTraversal dataLabel mapData =
- bgroup ("Unordered Traversals: " <> dataLabel)
- [ bench "unorderedTraverseWithKey_" $
- whnf (Map.unorderedTraverseWithKey_ (\_ i -> pure @Maybe (i ^ i) *> pure ())) mapData
- ]
-
-main :: IO ()
-main = do
- let !smallMap = testData 10
- !mediumMap = testData 1000
- !largeMap = testData 100000
- defaultMain
- [ benchOrderedTraversal "small" smallMap
- , benchUnorderedTraversal "small" smallMap
-
- , benchOrderedTraversal "medium" mediumMap
- , benchUnorderedTraversal "medium" mediumMap
-
- , benchOrderedTraversal "large" largeMap
- , benchUnorderedTraversal "large" largeMap
- ]
diff --git a/benchmark/parser/Main.hs b/benchmark/parser/Main.hs
index dcc0e23..e30312c 100644
--- a/benchmark/parser/Main.hs
+++ b/benchmark/parser/Main.hs
@@ -4,18 +4,19 @@
module Main where
import Control.Monad (forM)
-import Criterion.Main (defaultMain, bgroup, bench, whnf, nfIO)
import Data.Map (Map, foldrWithKey, singleton, unions)
import Data.Monoid ((<>))
+import Gauge (defaultMain, bgroup, bench, whnf, nfIO)
import System.Directory
import qualified Codec.Serialise
-import qualified Criterion.Main as Criterion
+import qualified Gauge
import qualified Data.ByteString.Lazy
import qualified Data.Text as T
import qualified Data.Text.IO as TIO
import qualified Dhall.Binary
+import qualified Dhall.Core as Dhall
import qualified Dhall.Parser as Dhall
#if MIN_VERSION_directory(1,2,3)
@@ -38,7 +39,7 @@ listDirectory path = filter f <$> getDirectoryContents path
type PreludeFiles = Map FilePath T.Text
loadPreludeFiles :: IO PreludeFiles
-loadPreludeFiles = loadDirectory "Prelude"
+loadPreludeFiles = loadDirectory "./dhall-lang/Prelude"
where
loadDirectory :: FilePath -> IO PreludeFiles
loadDirectory dir =
@@ -55,24 +56,25 @@ loadPreludeFiles = loadDirectory "Prelude"
loadFile :: FilePath -> IO PreludeFiles
loadFile path = singleton path <$> TIO.readFile path
-benchParser :: PreludeFiles -> Criterion.Benchmark
+benchParser :: PreludeFiles -> Gauge.Benchmark
benchParser =
bgroup "exprFromText"
. foldrWithKey (\name expr -> (benchExprFromText name expr :)) []
-benchExprFromText :: String -> T.Text -> Criterion.Benchmark
+benchExprFromText :: String -> T.Text -> Gauge.Benchmark
benchExprFromText name expr =
bench name $ whnf (Dhall.exprFromText "(input)") expr
benchExprFromBytes
- :: String -> Data.ByteString.Lazy.ByteString -> Criterion.Benchmark
+ :: String -> Data.ByteString.Lazy.ByteString -> Gauge.Benchmark
benchExprFromBytes name bytes = bench name (whnf f bytes)
where
f bytes = do
term <- case Codec.Serialise.deserialiseOrFail bytes of
Left _ -> Nothing
Right term -> return term
- case Dhall.Binary.decodeExpression term of
+ case Dhall.Binary.decodeExpression term
+ :: Either Dhall.Binary.DecodingFailure (Dhall.Expr () Dhall.Import) of
Left _ -> Nothing
Right expression -> return expression
diff --git a/dhall-lang/Prelude/JSON/Tagged b/dhall-lang/Prelude/JSON/Tagged
index 021b4c7..9cbd697 100644
--- a/dhall-lang/Prelude/JSON/Tagged
+++ b/dhall-lang/Prelude/JSON/Tagged
@@ -62,6 +62,16 @@ in { provisioners =
-}
let Tagged
: Type → Type
- = λ(a : Type) → { field : Text, nesting : ./Nesting, contents : a }
+ = λ ( a
+ : Type
+ )
+ → { field :
+ Text
+ , nesting :
+ ./Nesting sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335
+ ? ./Nesting
+ , contents :
+ a
+ }
in Tagged
diff --git a/dhall-lang/Prelude/JSON/package.dhall b/dhall-lang/Prelude/JSON/package.dhall
index e89006f..e84dbc2 100644
--- a/dhall-lang/Prelude/JSON/package.dhall
+++ b/dhall-lang/Prelude/JSON/package.dhall
@@ -4,4 +4,25 @@
, keyValue =
./keyValue sha256:a0a97199d280c4cce72ffcbbf93b7ceda0a569cf4d173ac98e0aaaa78034b98c
? ./keyValue
+, string =
+ ./string sha256:7a8ac435d30a96092d72889f3d48eabf7cba47ecf553fd6bc07a79fdf473e8d2
+ ? ./string
+, number =
+ ./number sha256:534745568065ae19d2b0fe1d09eeb071e9717d0f392187eb0bc95f386b018bec
+ ? ./number
+, object =
+ ./object sha256:a4e047cf157c3971b026b3942a87d474c85950d9b9654f8ebc8631740abf75a9
+ ? ./object
+, array =
+ ./array sha256:3a4c06cf135f4c80619e48c0808f6600d19782705bc59ee7c27cfc2e0f097eb7
+ ? ./array
+, bool =
+ ./bool sha256:018d29f030b45d642aba6bb81bf2c19a7bf183684612ce7a2c8afd2099783c48
+ ? ./bool
+, null =
+ ./null sha256:52c1d45ab2ca54875b444bfb1afdea497c8c9b0652e5044fafd8b16d97f4b78d
+ ? ./null
+, render =
+ ./render sha256:81f5a84efbb35211b1556838e86d17ed497912cf765bfa4ab76708b21e5371f1
+ ? ./render
}
diff --git a/dhall-lang/Prelude/Text/package.dhall b/dhall-lang/Prelude/Text/package.dhall
index 9536a2f..573abc4 100644
--- a/dhall-lang/Prelude/Text/package.dhall
+++ b/dhall-lang/Prelude/Text/package.dhall
@@ -1,14 +1,14 @@
{ concat =
- ./concat sha256:35e20d9403fbadb1a0061edb84e076ed56313709fa4bc8124d86ff54896f20ac
+ ./concat sha256:731265b0288e8a905ecff95c97333ee2db614c39d69f1514cb8eed9259745fc0
? ./concat
, concatMap =
- ./concatMap sha256:175d893ad7f2b2c05fff9e32f0d9cbadc7f5fce57945071508cf3603f8aa298e
+ ./concatMap sha256:7a0b0b99643de69d6f94ba49441cd0fa0507cbdfa8ace0295f16097af37e226f
? ./concatMap
, concatMapSep =
- ./concatMapSep sha256:46b81a9e211fb8278bf2793e75e8175fef79e0e3e478ef1016e3233ecc2ddfe6
+ ./concatMapSep sha256:c272aca80a607bc5963d1fcb38819e7e0d3e72ac4d02b1183b1afb6a91340840
? ./concatMapSep
, concatSep =
- ./concatSep sha256:d28e61f5057a240e857e09dba1b040fa3477bddb9659c5606c760852a9165890
+ ./concatSep sha256:e4401d69918c61b92a4c0288f7d60a6560ca99726138ed8ebc58dca2cd205e58
? ./concatSep
, show =
./show sha256:c9dc5de3e5f32872dbda57166804865e5e80785abe358ff61f1d8ac45f1f4784
diff --git a/dhall-lang/Prelude/package.dhall b/dhall-lang/Prelude/package.dhall
index d6d1be0..67da31a 100644
--- a/dhall-lang/Prelude/package.dhall
+++ b/dhall-lang/Prelude/package.dhall
@@ -13,6 +13,9 @@
, List =
./List/package.dhall sha256:108be3af5ebd465f7091039f2216c433e65ae5d25556a9a71786dd84d33ef49a
? ./List/package.dhall
+, Map =
+ ./Map/package.dhall sha256:07cc274220c8bdb2c1a0c2d00d90bc1447e73e0ad2e1d72b89773e923f77e71e
+ ? ./Map/package.dhall
, Natural =
./Natural/package.dhall sha256:fe08155c3a04500df847ca94d013ecd3dfc73ab5c136109b2414fce3ec42b63a
? ./Natural/package.dhall
@@ -20,9 +23,12 @@
./Optional/package.dhall sha256:36a366af67a3c26cd5d196e095d3023f18953c5b5db3a03956fa554609e5442a
? ./Optional/package.dhall
, JSON =
- ./JSON/package.dhall sha256:7f0c25a292e5d34ddfbbf3f6d90505567382f95d822b04f5810745f81ab1ef35
+ ./JSON/package.dhall sha256:34a613c89df3f314c606a813f592d1a09fedb3e5f5e63fcc0ae9c88245e8bdad
? ./JSON/package.dhall
, Text =
- ./Text/package.dhall sha256:c8bc93456397476051dc674c180ddd5db098546861c8df24bda8284511d3305e
+ ./Text/package.dhall sha256:3b6ed813caf2388b91056d625c6b958b72009f85a6af262d4a7b935b18caf62b
? ./Text/package.dhall
+, XML =
+ ./XML/package.dhall sha256:abace25be73c3ba823abfba92bb3742a0454d521804a5d19ab5dfbf966473a5d
+ ? ./XML/package.dhall
}
diff --git a/dhall-lang/tests/binary-decode/failure/unit/ApplyNoArgs.dhallb b/dhall-lang/tests/binary-decode/failure/unit/ApplyNoArgs.dhallb
new file mode 100644
index 0000000..451c2d5
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/failure/unit/ApplyNoArgs.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/failure/unit/LambdaExplicitlyNamedUnderscore.dhallb b/dhall-lang/tests/binary-decode/failure/unit/LambdaExplicitlyNamedUnderscore.dhallb
new file mode 100644
index 0000000..b5b67a3
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/failure/unit/LambdaExplicitlyNamedUnderscore.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/failure/unit/ListOneWithAnnotation.dhallb b/dhall-lang/tests/binary-decode/failure/unit/ListOneWithAnnotation.dhallb
new file mode 100644
index 0000000..e4d46ae
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/failure/unit/ListOneWithAnnotation.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/failure/unit/NaturalNegativeOne.dhallb b/dhall-lang/tests/binary-decode/failure/unit/NaturalNegativeOne.dhallb
new file mode 100644
index 0000000..1675457
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/failure/unit/NaturalNegativeOne.dhallb
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/dhall-lang/tests/binary-decode/failure/unit/OperatorOrTooFewArgs.dhallb b/dhall-lang/tests/binary-decode/failure/unit/OperatorOrTooFewArgs.dhallb
new file mode 100644
index 0000000..ae21d32
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/failure/unit/OperatorOrTooFewArgs.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/failure/unit/OperatorOrTooManyArgs.dhallb b/dhall-lang/tests/binary-decode/failure/unit/OperatorOrTooManyArgs.dhallb
new file mode 100644
index 0000000..485f6d0
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/failure/unit/OperatorOrTooManyArgs.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/failure/unit/OperatorUnknownOpcode.dhallb b/dhall-lang/tests/binary-decode/failure/unit/OperatorUnknownOpcode.dhallb
new file mode 100644
index 0000000..3084062
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/failure/unit/OperatorUnknownOpcode.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/failure/unit/PiExplicitlyNamedUnderscore.dhallb b/dhall-lang/tests/binary-decode/failure/unit/PiExplicitlyNamedUnderscore.dhallb
new file mode 100644
index 0000000..0185cab
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/failure/unit/PiExplicitlyNamedUnderscore.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/failure/unit/VariableExplicitlyNamedUnderscore.dhallb b/dhall-lang/tests/binary-decode/failure/unit/VariableExplicitlyNamedUnderscore.dhallb
new file mode 100644
index 0000000..ffc95bb
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/failure/unit/VariableExplicitlyNamedUnderscore.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/AnnotationA.dhallb b/dhall-lang/tests/binary-decode/success/unit/AnnotationA.dhallb
new file mode 100644
index 0000000..b9133f9
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/AnnotationA.dhallb
@@ -0,0 +1 @@
+gNatural \ No newline at end of file
diff --git a/dhall-lang/tests/binary-decode/success/unit/AnnotationB.dhall b/dhall-lang/tests/binary-decode/success/unit/AnnotationB.dhall
new file mode 100644
index 0000000..dd060c9
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/AnnotationB.dhall
@@ -0,0 +1 @@
+5 : Natural
diff --git a/dhall-lang/tests/binary-decode/success/unit/ApplicationA.dhallb b/dhall-lang/tests/binary-decode/success/unit/ApplicationA.dhallb
new file mode 100644
index 0000000..627f9e2
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/ApplicationA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/ApplicationB.dhall b/dhall-lang/tests/binary-decode/success/unit/ApplicationB.dhall
new file mode 100644
index 0000000..8ec1a7d
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/ApplicationB.dhall
@@ -0,0 +1 @@
+Natural/show _
diff --git a/dhall-lang/tests/binary-decode/success/unit/ApplicationMultipleA.dhallb b/dhall-lang/tests/binary-decode/success/unit/ApplicationMultipleA.dhallb
new file mode 100644
index 0000000..b58cc7a
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/ApplicationMultipleA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/ApplicationMultipleB.dhall b/dhall-lang/tests/binary-decode/success/unit/ApplicationMultipleB.dhall
new file mode 100644
index 0000000..71bbe20
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/ApplicationMultipleB.dhall
@@ -0,0 +1 @@
+f x y z
diff --git a/dhall-lang/tests/binary-decode/success/unit/BoolFalseA.dhallb b/dhall-lang/tests/binary-decode/success/unit/BoolFalseA.dhallb
new file mode 100644
index 0000000..3a6e607
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/BoolFalseA.dhallb
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/dhall-lang/tests/binary-decode/success/unit/BoolFalseB.dhall b/dhall-lang/tests/binary-decode/success/unit/BoolFalseB.dhall
new file mode 100644
index 0000000..bc59c12
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/BoolFalseB.dhall
@@ -0,0 +1 @@
+False
diff --git a/dhall-lang/tests/binary-decode/success/unit/BoolIfA.dhallb b/dhall-lang/tests/binary-decode/success/unit/BoolIfA.dhallb
new file mode 100644
index 0000000..d8ac90b
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/BoolIfA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/BoolIfB.dhall b/dhall-lang/tests/binary-decode/success/unit/BoolIfB.dhall
new file mode 100644
index 0000000..b1c30a1
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/BoolIfB.dhall
@@ -0,0 +1 @@
+if True then x else y
diff --git a/dhall-lang/tests/binary-decode/success/unit/BoolTrueA.dhallb b/dhall-lang/tests/binary-decode/success/unit/BoolTrueA.dhallb
new file mode 100644
index 0000000..bb7d13c
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/BoolTrueA.dhallb
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/dhall-lang/tests/binary-decode/success/unit/BoolTrueB.dhall b/dhall-lang/tests/binary-decode/success/unit/BoolTrueB.dhall
new file mode 100644
index 0000000..0ca9514
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/BoolTrueB.dhall
@@ -0,0 +1 @@
+True
diff --git a/dhall-lang/tests/binary-decode/success/unit/BuiltinNaturalShowA.dhallb b/dhall-lang/tests/binary-decode/success/unit/BuiltinNaturalShowA.dhallb
new file mode 100644
index 0000000..5f64a8a
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/BuiltinNaturalShowA.dhallb
@@ -0,0 +1 @@
+lNatural/show \ No newline at end of file
diff --git a/dhall-lang/tests/binary-decode/success/unit/BuiltinNaturalShowB.dhall b/dhall-lang/tests/binary-decode/success/unit/BuiltinNaturalShowB.dhall
new file mode 100644
index 0000000..2c4bdc5
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/BuiltinNaturalShowB.dhall
@@ -0,0 +1 @@
+Natural/show
diff --git a/dhall-lang/tests/binary-decode/success/unit/DoubleDoubleA.dhallb b/dhall-lang/tests/binary-decode/success/unit/DoubleDoubleA.dhallb
new file mode 100644
index 0000000..8d780d1
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/DoubleDoubleA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/DoubleDoubleB.dhall b/dhall-lang/tests/binary-decode/success/unit/DoubleDoubleB.dhall
new file mode 100644
index 0000000..f41cadd
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/DoubleDoubleB.dhall
@@ -0,0 +1,6 @@
+{-
+The CBOR for this is an (oversized) double-precision number. It could have been
+stored as single- (or even half-) precision, but we require decoders to accept
+it anyway.
+-}
+2.0
diff --git a/dhall-lang/tests/binary-decode/success/unit/DoubleHalfA.dhallb b/dhall-lang/tests/binary-decode/success/unit/DoubleHalfA.dhallb
new file mode 100644
index 0000000..ed788bb
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/DoubleHalfA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/DoubleHalfB.dhall b/dhall-lang/tests/binary-decode/success/unit/DoubleHalfB.dhall
new file mode 100644
index 0000000..8d48140
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/DoubleHalfB.dhall
@@ -0,0 +1,7 @@
+{-
+The CBOR for this is a half-precision number. Although dhall specifies that
+encoders should only use half-precision for infinities and NaN, it also
+specifies that decoders should tolerate floating point numbers with any
+precision.
+-}
+1.0
diff --git a/dhall-lang/tests/binary-decode/success/unit/DoubleInfinityA.dhallb b/dhall-lang/tests/binary-decode/success/unit/DoubleInfinityA.dhallb
new file mode 100644
index 0000000..2b119eb
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/DoubleInfinityA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/DoubleInfinityB.dhall b/dhall-lang/tests/binary-decode/success/unit/DoubleInfinityB.dhall
new file mode 100644
index 0000000..3c62151
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/DoubleInfinityB.dhall
@@ -0,0 +1 @@
+Infinity
diff --git a/dhall-lang/tests/binary-decode/success/unit/DoubleNegativeInfinityA.dhallb b/dhall-lang/tests/binary-decode/success/unit/DoubleNegativeInfinityA.dhallb
new file mode 100644
index 0000000..7c2eb64
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/DoubleNegativeInfinityA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/DoubleNegativeInfinityB.dhall b/dhall-lang/tests/binary-decode/success/unit/DoubleNegativeInfinityB.dhall
new file mode 100644
index 0000000..879e80e
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/DoubleNegativeInfinityB.dhall
@@ -0,0 +1 @@
+-Infinity
diff --git a/dhall-lang/tests/binary-decode/success/unit/DoubleSingleA.dhallb b/dhall-lang/tests/binary-decode/success/unit/DoubleSingleA.dhallb
new file mode 100644
index 0000000..81baf71
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/DoubleSingleA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/DoubleSingleB.dhall b/dhall-lang/tests/binary-decode/success/unit/DoubleSingleB.dhall
new file mode 100644
index 0000000..6d8b213
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/DoubleSingleB.dhall
@@ -0,0 +1,4 @@
+{-
+The CBOR for this is a single-precision number
+-}
+2.0
diff --git a/dhall-lang/tests/binary-decode/success/unit/IntegerNegativeOneA.dhallb b/dhall-lang/tests/binary-decode/success/unit/IntegerNegativeOneA.dhallb
new file mode 100644
index 0000000..e5376d3
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/IntegerNegativeOneA.dhallb
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/dhall-lang/tests/binary-decode/success/unit/IntegerNegativeOneB.dhall b/dhall-lang/tests/binary-decode/success/unit/IntegerNegativeOneB.dhall
new file mode 100644
index 0000000..3a2e3f4
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/IntegerNegativeOneB.dhall
@@ -0,0 +1 @@
+-1
diff --git a/dhall-lang/tests/binary-decode/success/unit/IntegerZeroA.dhallb b/dhall-lang/tests/binary-decode/success/unit/IntegerZeroA.dhallb
new file mode 100644
index 0000000..e99117f
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/IntegerZeroA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/IntegerZeroB.dhall b/dhall-lang/tests/binary-decode/success/unit/IntegerZeroB.dhall
new file mode 100644
index 0000000..9317bcb
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/IntegerZeroB.dhall
@@ -0,0 +1 @@
++0
diff --git a/dhall-lang/tests/binary-decode/success/unit/LambdaNamedXA.dhallb b/dhall-lang/tests/binary-decode/success/unit/LambdaNamedXA.dhallb
new file mode 100644
index 0000000..8d3e366
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/LambdaNamedXA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/LambdaNamedXB.dhall b/dhall-lang/tests/binary-decode/success/unit/LambdaNamedXB.dhall
new file mode 100644
index 0000000..570aeba
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/LambdaNamedXB.dhall
@@ -0,0 +1 @@
+λ(x : _) → x
diff --git a/dhall-lang/tests/binary-decode/success/unit/LambdaUnderscoreA.dhallb b/dhall-lang/tests/binary-decode/success/unit/LambdaUnderscoreA.dhallb
new file mode 100644
index 0000000..ed62afa
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/LambdaUnderscoreA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/LambdaUnderscoreB.dhall b/dhall-lang/tests/binary-decode/success/unit/LambdaUnderscoreB.dhall
new file mode 100644
index 0000000..19e4335
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/LambdaUnderscoreB.dhall
@@ -0,0 +1 @@
+λ(_ : Natural) → _
diff --git a/dhall-lang/tests/binary-decode/success/unit/LetMultipleA.dhallb b/dhall-lang/tests/binary-decode/success/unit/LetMultipleA.dhallb
new file mode 100644
index 0000000..84b9727
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/LetMultipleA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/LetMultipleB.dhall b/dhall-lang/tests/binary-decode/success/unit/LetMultipleB.dhall
new file mode 100644
index 0000000..50da0d5
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/LetMultipleB.dhall
@@ -0,0 +1 @@
+let x : Natural = 1 let y = 2 in x
diff --git a/dhall-lang/tests/binary-decode/success/unit/LetOneTypedA.dhallb b/dhall-lang/tests/binary-decode/success/unit/LetOneTypedA.dhallb
new file mode 100644
index 0000000..b4c9724
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/LetOneTypedA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/LetOneTypedB.dhall b/dhall-lang/tests/binary-decode/success/unit/LetOneTypedB.dhall
new file mode 100644
index 0000000..2e7c419
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/LetOneTypedB.dhall
@@ -0,0 +1 @@
+let x : Natural = 1 in x
diff --git a/dhall-lang/tests/binary-decode/success/unit/LetOneUntypedA.dhallb b/dhall-lang/tests/binary-decode/success/unit/LetOneUntypedA.dhallb
new file mode 100644
index 0000000..4f25135
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/LetOneUntypedA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/LetOneUntypedB.dhall b/dhall-lang/tests/binary-decode/success/unit/LetOneUntypedB.dhall
new file mode 100644
index 0000000..676607f
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/LetOneUntypedB.dhall
@@ -0,0 +1 @@
+let x = 1 in x
diff --git a/dhall-lang/tests/binary-decode/success/unit/ListEmptyA.dhallb b/dhall-lang/tests/binary-decode/success/unit/ListEmptyA.dhallb
new file mode 100644
index 0000000..d5df76e
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/ListEmptyA.dhallb
@@ -0,0 +1 @@
+gNatural \ No newline at end of file
diff --git a/dhall-lang/tests/binary-decode/success/unit/ListEmptyB.dhall b/dhall-lang/tests/binary-decode/success/unit/ListEmptyB.dhall
new file mode 100644
index 0000000..df05bac
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/ListEmptyB.dhall
@@ -0,0 +1 @@
+[] : List Natural
diff --git a/dhall-lang/tests/binary-decode/success/unit/ListOneA.dhallb b/dhall-lang/tests/binary-decode/success/unit/ListOneA.dhallb
new file mode 100644
index 0000000..7d2ad24
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/ListOneA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/ListOneB.dhall b/dhall-lang/tests/binary-decode/success/unit/ListOneB.dhall
new file mode 100644
index 0000000..4b0131f
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/ListOneB.dhall
@@ -0,0 +1 @@
+[ _ ]
diff --git a/dhall-lang/tests/binary-decode/success/unit/MergeAnnotatedA.dhallb b/dhall-lang/tests/binary-decode/success/unit/MergeAnnotatedA.dhallb
new file mode 100644
index 0000000..086e865
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/MergeAnnotatedA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/MergeAnnotatedB.dhall b/dhall-lang/tests/binary-decode/success/unit/MergeAnnotatedB.dhall
new file mode 100644
index 0000000..3e503ef
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/MergeAnnotatedB.dhall
@@ -0,0 +1 @@
+merge _ _@1 : _@2
diff --git a/dhall-lang/tests/binary-decode/success/unit/MergeUnannotatedA.dhallb b/dhall-lang/tests/binary-decode/success/unit/MergeUnannotatedA.dhallb
new file mode 100644
index 0000000..2e338a2
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/MergeUnannotatedA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/MergeUnannotatedB.dhall b/dhall-lang/tests/binary-decode/success/unit/MergeUnannotatedB.dhall
new file mode 100644
index 0000000..9ce9542
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/MergeUnannotatedB.dhall
@@ -0,0 +1 @@
+merge _ _@1
diff --git a/dhall-lang/tests/binary-decode/success/unit/NaturalTwentyFourA.dhallb b/dhall-lang/tests/binary-decode/success/unit/NaturalTwentyFourA.dhallb
new file mode 100644
index 0000000..20074f4
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/NaturalTwentyFourA.dhallb
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/dhall-lang/tests/binary-decode/success/unit/NaturalTwentyFourB.dhall b/dhall-lang/tests/binary-decode/success/unit/NaturalTwentyFourB.dhall
new file mode 100644
index 0000000..8baef9d
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/NaturalTwentyFourB.dhall
@@ -0,0 +1,5 @@
+{-
+24 is the first natural number that has a different CBOR encoding, hence the
+separate test here.
+-}
+24
diff --git a/dhall-lang/tests/binary-decode/success/unit/NaturalZeroA.dhallb b/dhall-lang/tests/binary-decode/success/unit/NaturalZeroA.dhallb
new file mode 100644
index 0000000..3209e83
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/NaturalZeroA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/NaturalZeroB.dhall b/dhall-lang/tests/binary-decode/success/unit/NaturalZeroB.dhall
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/NaturalZeroB.dhall
@@ -0,0 +1 @@
+0
diff --git a/dhall-lang/tests/binary-decode/success/unit/OperatorAndA.dhallb b/dhall-lang/tests/binary-decode/success/unit/OperatorAndA.dhallb
new file mode 100644
index 0000000..53168e7
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/OperatorAndA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/OperatorAndB.dhall b/dhall-lang/tests/binary-decode/success/unit/OperatorAndB.dhall
new file mode 100644
index 0000000..a76fcac
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/OperatorAndB.dhall
@@ -0,0 +1 @@
+_ && _@1
diff --git a/dhall-lang/tests/binary-decode/success/unit/OperatorCombineA.dhallb b/dhall-lang/tests/binary-decode/success/unit/OperatorCombineA.dhallb
new file mode 100644
index 0000000..66c8d0f
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/OperatorCombineA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/OperatorCombineB.dhall b/dhall-lang/tests/binary-decode/success/unit/OperatorCombineB.dhall
new file mode 100644
index 0000000..55f8284
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/OperatorCombineB.dhall
@@ -0,0 +1 @@
+_ ∧ _@1
diff --git a/dhall-lang/tests/binary-decode/success/unit/OperatorCombineTypesA.dhallb b/dhall-lang/tests/binary-decode/success/unit/OperatorCombineTypesA.dhallb
new file mode 100644
index 0000000..b0c3bd4
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/OperatorCombineTypesA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/OperatorCombineTypesB.dhall b/dhall-lang/tests/binary-decode/success/unit/OperatorCombineTypesB.dhall
new file mode 100644
index 0000000..86ac1d2
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/OperatorCombineTypesB.dhall
@@ -0,0 +1 @@
+_ ⩓ _@1
diff --git a/dhall-lang/tests/binary-decode/success/unit/OperatorEqA.dhallb b/dhall-lang/tests/binary-decode/success/unit/OperatorEqA.dhallb
new file mode 100644
index 0000000..612fd4f
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/OperatorEqA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/OperatorEqB.dhall b/dhall-lang/tests/binary-decode/success/unit/OperatorEqB.dhall
new file mode 100644
index 0000000..8a170d1
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/OperatorEqB.dhall
@@ -0,0 +1 @@
+_ == _@1
diff --git a/dhall-lang/tests/binary-decode/success/unit/OperatorImportAltA.dhallb b/dhall-lang/tests/binary-decode/success/unit/OperatorImportAltA.dhallb
new file mode 100644
index 0000000..9958505
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/OperatorImportAltA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/OperatorImportAltB.dhall b/dhall-lang/tests/binary-decode/success/unit/OperatorImportAltB.dhall
new file mode 100644
index 0000000..97fd510
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/OperatorImportAltB.dhall
@@ -0,0 +1 @@
+_ ? _@1
diff --git a/dhall-lang/tests/binary-decode/success/unit/OperatorListAppendA.dhallb b/dhall-lang/tests/binary-decode/success/unit/OperatorListAppendA.dhallb
new file mode 100644
index 0000000..25dfe4a
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/OperatorListAppendA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/OperatorListAppendB.dhall b/dhall-lang/tests/binary-decode/success/unit/OperatorListAppendB.dhall
new file mode 100644
index 0000000..d1fcafb
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/OperatorListAppendB.dhall
@@ -0,0 +1 @@
+_ # _@1
diff --git a/dhall-lang/tests/binary-decode/success/unit/OperatorNeqA.dhallb b/dhall-lang/tests/binary-decode/success/unit/OperatorNeqA.dhallb
new file mode 100644
index 0000000..59bce32
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/OperatorNeqA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/OperatorNeqB.dhall b/dhall-lang/tests/binary-decode/success/unit/OperatorNeqB.dhall
new file mode 100644
index 0000000..1f59f70
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/OperatorNeqB.dhall
@@ -0,0 +1 @@
+_ != _@1
diff --git a/dhall-lang/tests/binary-decode/success/unit/OperatorOrA.dhallb b/dhall-lang/tests/binary-decode/success/unit/OperatorOrA.dhallb
new file mode 100644
index 0000000..8533ec3
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/OperatorOrA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/OperatorOrB.dhall b/dhall-lang/tests/binary-decode/success/unit/OperatorOrB.dhall
new file mode 100644
index 0000000..3c2480a
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/OperatorOrB.dhall
@@ -0,0 +1 @@
+_ || _@1
diff --git a/dhall-lang/tests/binary-decode/success/unit/OperatorPlusA.dhallb b/dhall-lang/tests/binary-decode/success/unit/OperatorPlusA.dhallb
new file mode 100644
index 0000000..1a465e8
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/OperatorPlusA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/OperatorPlusB.dhall b/dhall-lang/tests/binary-decode/success/unit/OperatorPlusB.dhall
new file mode 100644
index 0000000..7c0ceaa
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/OperatorPlusB.dhall
@@ -0,0 +1 @@
+_ + _@1
diff --git a/dhall-lang/tests/binary-decode/success/unit/OperatorPreferA.dhallb b/dhall-lang/tests/binary-decode/success/unit/OperatorPreferA.dhallb
new file mode 100644
index 0000000..9192806
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/OperatorPreferA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/OperatorPreferB.dhall b/dhall-lang/tests/binary-decode/success/unit/OperatorPreferB.dhall
new file mode 100644
index 0000000..d647a1e
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/OperatorPreferB.dhall
@@ -0,0 +1 @@
+_ ⫽ _@1
diff --git a/dhall-lang/tests/binary-decode/success/unit/OperatorTextAppendA.dhallb b/dhall-lang/tests/binary-decode/success/unit/OperatorTextAppendA.dhallb
new file mode 100644
index 0000000..f15a26e
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/OperatorTextAppendA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/OperatorTextAppendB.dhall b/dhall-lang/tests/binary-decode/success/unit/OperatorTextAppendB.dhall
new file mode 100644
index 0000000..83ab6e1
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/OperatorTextAppendB.dhall
@@ -0,0 +1 @@
+_ ++ _@1
diff --git a/dhall-lang/tests/binary-decode/success/unit/OperatorTimesA.dhallb b/dhall-lang/tests/binary-decode/success/unit/OperatorTimesA.dhallb
new file mode 100644
index 0000000..01eda29
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/OperatorTimesA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/OperatorTimesB.dhall b/dhall-lang/tests/binary-decode/success/unit/OperatorTimesB.dhall
new file mode 100644
index 0000000..2f19b0f
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/OperatorTimesB.dhall
@@ -0,0 +1 @@
+_ * _@1
diff --git a/dhall-lang/tests/binary-decode/success/unit/PiNamedXA.dhallb b/dhall-lang/tests/binary-decode/success/unit/PiNamedXA.dhallb
new file mode 100644
index 0000000..c56c19e
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/PiNamedXA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/PiNamedXB.dhall b/dhall-lang/tests/binary-decode/success/unit/PiNamedXB.dhall
new file mode 100644
index 0000000..f08089e
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/PiNamedXB.dhall
@@ -0,0 +1 @@
+∀(x : Natural) → _
diff --git a/dhall-lang/tests/binary-decode/success/unit/PiUnderscoreA.dhallb b/dhall-lang/tests/binary-decode/success/unit/PiUnderscoreA.dhallb
new file mode 100644
index 0000000..c92078e
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/PiUnderscoreA.dhallb
@@ -0,0 +1 @@
+gNaturaldText \ No newline at end of file
diff --git a/dhall-lang/tests/binary-decode/success/unit/PiUnderscoreB.dhall b/dhall-lang/tests/binary-decode/success/unit/PiUnderscoreB.dhall
new file mode 100644
index 0000000..a2b0041
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/PiUnderscoreB.dhall
@@ -0,0 +1 @@
+Natural → Text
diff --git a/dhall-lang/tests/binary-decode/success/unit/RecordFieldAccessA.dhallb b/dhall-lang/tests/binary-decode/success/unit/RecordFieldAccessA.dhallb
new file mode 100644
index 0000000..6130a66
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/RecordFieldAccessA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/RecordFieldAccessB.dhall b/dhall-lang/tests/binary-decode/success/unit/RecordFieldAccessB.dhall
new file mode 100644
index 0000000..fa092e7
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/RecordFieldAccessB.dhall
@@ -0,0 +1 @@
+_.x
diff --git a/dhall-lang/tests/binary-decode/success/unit/RecordLiteralA.dhallb b/dhall-lang/tests/binary-decode/success/unit/RecordLiteralA.dhallb
new file mode 100644
index 0000000..59f757b
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/RecordLiteralA.dhallb
@@ -0,0 +1 @@
+axgNaturalaydBool \ No newline at end of file
diff --git a/dhall-lang/tests/binary-decode/success/unit/RecordLiteralB.dhall b/dhall-lang/tests/binary-decode/success/unit/RecordLiteralB.dhall
new file mode 100644
index 0000000..c0d98a7
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/RecordLiteralB.dhall
@@ -0,0 +1 @@
+{ x = Natural, y = Bool }
diff --git a/dhall-lang/tests/binary-decode/success/unit/RecordProjectFieldsA.dhallb b/dhall-lang/tests/binary-decode/success/unit/RecordProjectFieldsA.dhallb
new file mode 100644
index 0000000..46cea17
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/RecordProjectFieldsA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/RecordProjectFieldsB.dhall b/dhall-lang/tests/binary-decode/success/unit/RecordProjectFieldsB.dhall
new file mode 100644
index 0000000..ea86639
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/RecordProjectFieldsB.dhall
@@ -0,0 +1 @@
+r.{ x, y, z }
diff --git a/dhall-lang/tests/binary-decode/success/unit/RecordTypeA.dhallb b/dhall-lang/tests/binary-decode/success/unit/RecordTypeA.dhallb
new file mode 100644
index 0000000..65c6ad2
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/RecordTypeA.dhallb
@@ -0,0 +1 @@
+axgNaturalaydBool \ No newline at end of file
diff --git a/dhall-lang/tests/binary-decode/success/unit/RecordTypeB.dhall b/dhall-lang/tests/binary-decode/success/unit/RecordTypeB.dhall
new file mode 100644
index 0000000..300a0a6
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/RecordTypeB.dhall
@@ -0,0 +1 @@
+{ x : Natural, y : Bool }
diff --git a/dhall-lang/tests/binary-decode/success/unit/SomeA.dhallb b/dhall-lang/tests/binary-decode/success/unit/SomeA.dhallb
new file mode 100644
index 0000000..a3192f8
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/SomeA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/SomeB.dhall b/dhall-lang/tests/binary-decode/success/unit/SomeB.dhall
new file mode 100644
index 0000000..bcd3609
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/SomeB.dhall
@@ -0,0 +1 @@
+Some _
diff --git a/dhall-lang/tests/binary-decode/success/unit/TextInterpolatedA.dhallb b/dhall-lang/tests/binary-decode/success/unit/TextInterpolatedA.dhallb
new file mode 100644
index 0000000..166516f
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/TextInterpolatedA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/TextInterpolatedB.dhall b/dhall-lang/tests/binary-decode/success/unit/TextInterpolatedB.dhall
new file mode 100644
index 0000000..fb5a6e4
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/TextInterpolatedB.dhall
@@ -0,0 +1 @@
+"foo${_}bar"
diff --git a/dhall-lang/tests/binary-decode/success/unit/TextSimpleA.dhallb b/dhall-lang/tests/binary-decode/success/unit/TextSimpleA.dhallb
new file mode 100644
index 0000000..a57789b
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/TextSimpleA.dhallb
@@ -0,0 +1 @@
+cfoo \ No newline at end of file
diff --git a/dhall-lang/tests/binary-decode/success/unit/TextSimpleB.dhall b/dhall-lang/tests/binary-decode/success/unit/TextSimpleB.dhall
new file mode 100644
index 0000000..810c96e
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/TextSimpleB.dhall
@@ -0,0 +1 @@
+"foo"
diff --git a/dhall-lang/tests/binary-decode/success/unit/UnionTypeA.dhallb b/dhall-lang/tests/binary-decode/success/unit/UnionTypeA.dhallb
new file mode 100644
index 0000000..59a024a
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/UnionTypeA.dhallb
@@ -0,0 +1 @@
+ axgNaturalay \ No newline at end of file
diff --git a/dhall-lang/tests/binary-decode/success/unit/UnionTypeB.dhall b/dhall-lang/tests/binary-decode/success/unit/UnionTypeB.dhall
new file mode 100644
index 0000000..e93e34c
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/UnionTypeB.dhall
@@ -0,0 +1 @@
+< x : Natural | y >
diff --git a/dhall-lang/tests/binary-decode/success/unit/VariableNamedA.dhallb b/dhall-lang/tests/binary-decode/success/unit/VariableNamedA.dhallb
new file mode 100644
index 0000000..d759864
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/VariableNamedA.dhallb
@@ -0,0 +1 @@
+ax \ No newline at end of file
diff --git a/dhall-lang/tests/binary-decode/success/unit/VariableNamedB.dhall b/dhall-lang/tests/binary-decode/success/unit/VariableNamedB.dhall
new file mode 100644
index 0000000..34ace29
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/VariableNamedB.dhall
@@ -0,0 +1 @@
+x@1
diff --git a/dhall-lang/tests/binary-decode/success/unit/VariableNamedOversizedIntA.dhallb b/dhall-lang/tests/binary-decode/success/unit/VariableNamedOversizedIntA.dhallb
new file mode 100644
index 0000000..c41937b
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/VariableNamedOversizedIntA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/VariableNamedOversizedIntB.dhall b/dhall-lang/tests/binary-decode/success/unit/VariableNamedOversizedIntB.dhall
new file mode 100644
index 0000000..f0c4ea3
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/VariableNamedOversizedIntB.dhall
@@ -0,0 +1,16 @@
+{-
+
+This file tests that a number encoded as a type larger than required is still
+read successfully. In this case, the .dhallb file has the bytes:
+
+ 8261 781b 0000 0000 0000 0001
+
+which means the array ["x", uint64(1)]. This could have been stored in fewer
+bytes as
+
+ 8261 7801
+
+but decoders are required to allow the oversized representation.
+
+-}
+x@1
diff --git a/dhall-lang/tests/binary-decode/success/unit/VariableUnderscoreA.dhallb b/dhall-lang/tests/binary-decode/success/unit/VariableUnderscoreA.dhallb
new file mode 100644
index 0000000..45a8ca0
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/VariableUnderscoreA.dhallb
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/dhall-lang/tests/binary-decode/success/unit/VariableUnderscoreB.dhall b/dhall-lang/tests/binary-decode/success/unit/VariableUnderscoreB.dhall
new file mode 100644
index 0000000..ddbfb03
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/VariableUnderscoreB.dhall
@@ -0,0 +1 @@
+_@4
diff --git a/dhall-lang/tests/binary-decode/success/unit/VariableUnderscoreOversizedIntA.dhallb b/dhall-lang/tests/binary-decode/success/unit/VariableUnderscoreOversizedIntA.dhallb
new file mode 100644
index 0000000..3d12921
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/VariableUnderscoreOversizedIntA.dhallb
Binary files differ
diff --git a/dhall-lang/tests/binary-decode/success/unit/VariableUnderscoreOversizedIntB.dhall b/dhall-lang/tests/binary-decode/success/unit/VariableUnderscoreOversizedIntB.dhall
new file mode 100644
index 0000000..e02aa4c
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/VariableUnderscoreOversizedIntB.dhall
@@ -0,0 +1,13 @@
+{-
+
+This file tests that a number encoded as a type larger than required is still
+read successfully. In this case, the .dhallb file has the bytes:
+
+ 1b00 0000 0000 0000 01
+
+which means a uint64 with value 1. The number 1 could have been stored in a
+single byte as 01, but decoders are required to allow the oversized
+representation.
+
+-}
+_@1
diff --git a/dhall-lang/tests/binary-decode/success/unit/recordProjectionByExpressionA.dhallb b/dhall-lang/tests/binary-decode/success/unit/recordProjectionByExpressionA.dhallb
new file mode 100644
index 0000000..51de1f5
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/recordProjectionByExpressionA.dhallb
@@ -0,0 +1,2 @@
+
+aaabaagNatural \ No newline at end of file
diff --git a/dhall-lang/tests/binary-decode/success/unit/recordProjectionByExpressionB.dhall b/dhall-lang/tests/binary-decode/success/unit/recordProjectionByExpressionB.dhall
new file mode 100644
index 0000000..b083b0c
--- /dev/null
+++ b/dhall-lang/tests/binary-decode/success/unit/recordProjectionByExpressionB.dhall
@@ -0,0 +1 @@
+{ a = 1, b = 2 }.({ a : Natural })
diff --git a/dhall-lang/tests/import/cache/dhall/1220efc43103e49b56c5bf089db8e0365bbfc455b8a2f0dc6ee5727a3586f85969fd b/dhall-lang/tests/import/cache/dhall/1220efc43103e49b56c5bf089db8e0365bbfc455b8a2f0dc6ee5727a3586f85969fd
new file mode 100644
index 0000000..1e6063a
--- /dev/null
+++ b/dhall-lang/tests/import/cache/dhall/1220efc43103e49b56c5bf089db8e0365bbfc455b8a2f0dc6ee5727a3586f85969fd
Binary files differ
diff --git a/dhall-lang/tests/import/data/simpleLocation.dhall b/dhall-lang/tests/import/data/simpleLocation.dhall
new file mode 100644
index 0000000..1d3e43b
--- /dev/null
+++ b/dhall-lang/tests/import/data/simpleLocation.dhall
@@ -0,0 +1 @@
+./simple.dhall as Location
diff --git a/dhall-lang/tests/import/success/asLocationA.dhall b/dhall-lang/tests/import/success/asLocationA.dhall
new file mode 100644
index 0000000..6d67ace
--- /dev/null
+++ b/dhall-lang/tests/import/success/asLocationA.dhall
@@ -0,0 +1,8 @@
+{ _1 = ./some/import.dhall as Location
+, _2 = ../data/simpleLocation.dhall
+, _3 = /absolute/import sha256:f9340badf94a684e652e0a384f64363293d8b632d971f3453f7ee22f10ab6e75 as Location
+, _4 = https://prelude.dhall-lang.org/package.dhall as Location
+, _5 = env:HOME as Location
+, _6 = missing as Location
+, _7 = (missing as Location) ? 42 -- `missing` fails as an import, but definitely resolves as Location
+}
diff --git a/dhall-lang/tests/import/success/asLocationB.dhall b/dhall-lang/tests/import/success/asLocationB.dhall
new file mode 100644
index 0000000..0fa7f92
--- /dev/null
+++ b/dhall-lang/tests/import/success/asLocationB.dhall
@@ -0,0 +1,8 @@
+{ _1 = < Local : Text | Remote : Text | Environment : Text | Missing >.Local "./some/import.dhall"
+, _2 = < Local : Text | Remote : Text | Environment : Text | Missing >.Local "../data/simple.dhall"
+, _3 = < Local : Text | Remote : Text | Environment : Text | Missing >.Local "/absolute/import"
+, _4 = < Local : Text | Remote : Text | Environment : Text | Missing >.Remote "https://prelude.dhall-lang.org/package.dhall"
+, _5 = < Local : Text | Remote : Text | Environment : Text | Missing >.Environment "env:HOME"
+, _6 = < Local : Text | Remote : Text | Environment : Text | Missing >.Missing
+, _7 = < Local : Text | Remote : Text | Environment : Text | Missing >.Missing
+}
diff --git a/dhall-lang/tests/import/success/customHeadersA.dhall b/dhall-lang/tests/import/success/customHeadersA.dhall
index c0d7454..e94af59 100644
--- a/dhall-lang/tests/import/success/customHeadersA.dhall
+++ b/dhall-lang/tests/import/success/customHeadersA.dhall
@@ -1,3 +1,3 @@
https://httpbin.org/user-agent
- using [ { header = "User-Agent", value = "Dhall" } ]
+ using [ { mapKey = "User-Agent", mapValue = "Dhall" } ]
as Text
diff --git a/dhall-lang/tests/import/success/hashFromCacheA.dhall b/dhall-lang/tests/import/success/hashFromCacheA.dhall
new file mode 100644
index 0000000..ff62b0c
--- /dev/null
+++ b/dhall-lang/tests/import/success/hashFromCacheA.dhall
@@ -0,0 +1,11 @@
+{-
+An import with an integrity check MUST be fetched from the cache if possible.
+
+If you have set XDG_CACHE_HOME as described in tests/README.md, this hash will
+be available in the cache, so even though this is a `missing` import, it can be
+resolved by its hash.
+
+(If you're interested, the value is a fully-αβ-normalized copy of
+Prelude/Optional/null at time of test creation)
+-}
+missing sha256:efc43103e49b56c5bf089db8e0365bbfc455b8a2f0dc6ee5727a3586f85969fd
diff --git a/dhall-lang/tests/import/success/hashFromCacheB.dhall b/dhall-lang/tests/import/success/hashFromCacheB.dhall
new file mode 100644
index 0000000..63a6c95
--- /dev/null
+++ b/dhall-lang/tests/import/success/hashFromCacheB.dhall
@@ -0,0 +1,3 @@
+ λ(_ : Type)
+→ λ(_ : Optional _)
+→ Optional/fold _@1 _ Bool (λ(_ : _@1) → False) True
diff --git a/dhall-lang/tests/import/success/headerForwardingA.dhall b/dhall-lang/tests/import/success/headerForwardingA.dhall
index f06d11f..5908af0 100644
--- a/dhall-lang/tests/import/success/headerForwardingA.dhall
+++ b/dhall-lang/tests/import/success/headerForwardingA.dhall
@@ -13,4 +13,4 @@
Prelude changes (sorry)
-}
https://test.dhall-lang.org/Bool/package.dhall
- using [ { header = "Test", value = "Example" } ]
+ using [ { mapKey = "Test", mapValue = "Example" } ]
diff --git a/dhall-lang/tests/import/success/noHeaderForwardingA.dhall b/dhall-lang/tests/import/success/noHeaderForwardingA.dhall
index 711fc10..9872527 100644
--- a/dhall-lang/tests/import/success/noHeaderForwardingA.dhall
+++ b/dhall-lang/tests/import/success/noHeaderForwardingA.dhall
@@ -3,4 +3,4 @@
https://httpbin.org/user-agent
-}
https://raw.githubusercontent.com/dhall-lang/dhall-lang/master/tests/import/success/customHeadersA.dhall
- using [ { header = "User-Agent", value = "Secret" } ]
+ using [ { mapKey = "User-Agent", mapValue = "Secret" } ]
diff --git a/dhall-lang/tests/normalization/success/simple/equalNoCommuteA.dhall b/dhall-lang/tests/normalization/success/simple/equalNoCommuteA.dhall
new file mode 100644
index 0000000..7b45db6
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/simple/equalNoCommuteA.dhall
@@ -0,0 +1 @@
+λ(x : Bool) → x == False
diff --git a/dhall-lang/tests/normalization/success/simple/equalNoCommuteB.dhall b/dhall-lang/tests/normalization/success/simple/equalNoCommuteB.dhall
new file mode 100644
index 0000000..7b45db6
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/simple/equalNoCommuteB.dhall
@@ -0,0 +1 @@
+λ(x : Bool) → x == False
diff --git a/dhall-lang/tests/normalization/success/simple/notEqualNoCommuteA.dhall b/dhall-lang/tests/normalization/success/simple/notEqualNoCommuteA.dhall
new file mode 100644
index 0000000..6f95dc6
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/simple/notEqualNoCommuteA.dhall
@@ -0,0 +1 @@
+λ(x : Bool) → x != True
diff --git a/dhall-lang/tests/normalization/success/simple/notEqualNoCommuteB.dhall b/dhall-lang/tests/normalization/success/simple/notEqualNoCommuteB.dhall
new file mode 100644
index 0000000..6f95dc6
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/simple/notEqualNoCommuteB.dhall
@@ -0,0 +1 @@
+λ(x : Bool) → x != True
diff --git a/dhall-lang/tests/normalization/success/simple/plusNoCommuteA.dhall b/dhall-lang/tests/normalization/success/simple/plusNoCommuteA.dhall
new file mode 100644
index 0000000..87da0f1
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/simple/plusNoCommuteA.dhall
@@ -0,0 +1 @@
+λ(x : Natural) → x + 1
diff --git a/dhall-lang/tests/normalization/success/simple/plusNoCommuteB.dhall b/dhall-lang/tests/normalization/success/simple/plusNoCommuteB.dhall
new file mode 100644
index 0000000..87da0f1
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/simple/plusNoCommuteB.dhall
@@ -0,0 +1 @@
+λ(x : Natural) → x + 1
diff --git a/dhall-lang/tests/normalization/success/simple/timesNoCommuteA.dhall b/dhall-lang/tests/normalization/success/simple/timesNoCommuteA.dhall
new file mode 100644
index 0000000..d148448
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/simple/timesNoCommuteA.dhall
@@ -0,0 +1 @@
+λ(x : Natural) → x * 2
diff --git a/dhall-lang/tests/normalization/success/simple/timesNoCommuteB.dhall b/dhall-lang/tests/normalization/success/simple/timesNoCommuteB.dhall
new file mode 100644
index 0000000..d148448
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/simple/timesNoCommuteB.dhall
@@ -0,0 +1 @@
+λ(x : Natural) → x * 2
diff --git a/dhall-lang/tests/normalization/success/unit/EmptyToMapA.dhall b/dhall-lang/tests/normalization/success/unit/EmptyToMapA.dhall
new file mode 100644
index 0000000..9abd6d2
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/unit/EmptyToMapA.dhall
@@ -0,0 +1 @@
+toMap {=} : List {mapKey : Text, mapValue : Natural}
diff --git a/dhall-lang/tests/normalization/success/unit/EmptyToMapB.dhall b/dhall-lang/tests/normalization/success/unit/EmptyToMapB.dhall
new file mode 100644
index 0000000..05d70a8
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/unit/EmptyToMapB.dhall
@@ -0,0 +1 @@
+[] : List { mapKey : Text, mapValue : Natural }
diff --git a/dhall-lang/tests/normalization/success/unit/ListNormalizeTypeAnnotationA.dhall b/dhall-lang/tests/normalization/success/unit/ListNormalizeTypeAnnotationA.dhall
index 46e1c64..ba59ac6 100644
--- a/dhall-lang/tests/normalization/success/unit/ListNormalizeTypeAnnotationA.dhall
+++ b/dhall-lang/tests/normalization/success/unit/ListNormalizeTypeAnnotationA.dhall
@@ -1 +1 @@
-[] : List (if True then x else y)
+[] : { x = List Bool }.x
diff --git a/dhall-lang/tests/normalization/success/unit/ListNormalizeTypeAnnotationB.dhall b/dhall-lang/tests/normalization/success/unit/ListNormalizeTypeAnnotationB.dhall
index c43e76f..3b99552 100644
--- a/dhall-lang/tests/normalization/success/unit/ListNormalizeTypeAnnotationB.dhall
+++ b/dhall-lang/tests/normalization/success/unit/ListNormalizeTypeAnnotationB.dhall
@@ -1 +1 @@
-[] : List x
+[] : List Bool
diff --git a/dhall-lang/tests/normalization/success/unit/NoneNaturalA.dhall b/dhall-lang/tests/normalization/success/unit/NoneNaturalA.dhall
deleted file mode 100644
index 1a1eece..0000000
--- a/dhall-lang/tests/normalization/success/unit/NoneNaturalA.dhall
+++ /dev/null
@@ -1 +0,0 @@
-[] : Optional Natural
diff --git a/dhall-lang/tests/normalization/success/unit/NoneNaturalB.dhall b/dhall-lang/tests/normalization/success/unit/NoneNaturalB.dhall
deleted file mode 100644
index 3bc82ca..0000000
--- a/dhall-lang/tests/normalization/success/unit/NoneNaturalB.dhall
+++ /dev/null
@@ -1 +0,0 @@
-None Natural
diff --git a/dhall-lang/tests/normalization/success/unit/RecordProjectionTypeEmptyA.dhall b/dhall-lang/tests/normalization/success/unit/RecordProjectionByTypeEmptyA.dhall
index 043fc3d..043fc3d 100644
--- a/dhall-lang/tests/normalization/success/unit/RecordProjectionTypeEmptyA.dhall
+++ b/dhall-lang/tests/normalization/success/unit/RecordProjectionByTypeEmptyA.dhall
diff --git a/dhall-lang/tests/normalization/success/unit/RecordProjectionTypeEmptyB.dhall b/dhall-lang/tests/normalization/success/unit/RecordProjectionByTypeEmptyB.dhall
index 339130f..339130f 100644
--- a/dhall-lang/tests/normalization/success/unit/RecordProjectionTypeEmptyB.dhall
+++ b/dhall-lang/tests/normalization/success/unit/RecordProjectionByTypeEmptyB.dhall
diff --git a/dhall-lang/tests/normalization/success/unit/RecordProjectionTypeNonEmptyA.dhall b/dhall-lang/tests/normalization/success/unit/RecordProjectionByTypeNonEmptyA.dhall
index a4331fa..a4331fa 100644
--- a/dhall-lang/tests/normalization/success/unit/RecordProjectionTypeNonEmptyA.dhall
+++ b/dhall-lang/tests/normalization/success/unit/RecordProjectionByTypeNonEmptyA.dhall
diff --git a/dhall-lang/tests/normalization/success/unit/RecordProjectionTypeNonEmptyB.dhall b/dhall-lang/tests/normalization/success/unit/RecordProjectionByTypeNonEmptyB.dhall
index ba31b3b..ba31b3b 100644
--- a/dhall-lang/tests/normalization/success/unit/RecordProjectionTypeNonEmptyB.dhall
+++ b/dhall-lang/tests/normalization/success/unit/RecordProjectionByTypeNonEmptyB.dhall
diff --git a/dhall-lang/tests/normalization/success/unit/RecordProjectionByTypeNormalizeProjectionA.dhall b/dhall-lang/tests/normalization/success/unit/RecordProjectionByTypeNormalizeProjectionA.dhall
new file mode 100644
index 0000000..5abef15
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/unit/RecordProjectionByTypeNormalizeProjectionA.dhall
@@ -0,0 +1 @@
+x.({ a : Natural, b : Natural })
diff --git a/dhall-lang/tests/normalization/success/unit/RecordProjectionByTypeNormalizeProjectionB.dhall b/dhall-lang/tests/normalization/success/unit/RecordProjectionByTypeNormalizeProjectionB.dhall
new file mode 100644
index 0000000..a716868
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/unit/RecordProjectionByTypeNormalizeProjectionB.dhall
@@ -0,0 +1 @@
+x.{ a, b }
diff --git a/dhall-lang/tests/normalization/success/unit/RecordProjectionNormalizeFieldsA.dhall b/dhall-lang/tests/normalization/success/unit/RecordProjectionNormalizeFieldsA.dhall
new file mode 100644
index 0000000..85357a1
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/unit/RecordProjectionNormalizeFieldsA.dhall
@@ -0,0 +1 @@
+λ(x : { a : Bool, b : Bool, c : Bool }) → x.{ c, a }
diff --git a/dhall-lang/tests/normalization/success/unit/RecordProjectionNormalizeFieldsB.dhall b/dhall-lang/tests/normalization/success/unit/RecordProjectionNormalizeFieldsB.dhall
new file mode 100644
index 0000000..f20900e
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/unit/RecordProjectionNormalizeFieldsB.dhall
@@ -0,0 +1 @@
+λ(x : { a : Bool, b : Bool, c : Bool }) → x.{ a, c }
diff --git a/dhall-lang/tests/normalization/success/unit/ToMapA.dhall b/dhall-lang/tests/normalization/success/unit/ToMapA.dhall
new file mode 100644
index 0000000..5353bf3
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/unit/ToMapA.dhall
@@ -0,0 +1 @@
+toMap { foo= 1, bar= 4, baz= 9 }
diff --git a/dhall-lang/tests/normalization/success/unit/ToMapB.dhall b/dhall-lang/tests/normalization/success/unit/ToMapB.dhall
new file mode 100644
index 0000000..e1e0b20
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/unit/ToMapB.dhall
@@ -0,0 +1,4 @@
+[ { mapKey = "bar", mapValue = 4 }
+, { mapKey = "baz", mapValue = 9 }
+, { mapKey = "foo", mapValue = 1 }
+]
diff --git a/dhall-lang/tests/normalization/success/unit/ToMapWithTypeA.dhall b/dhall-lang/tests/normalization/success/unit/ToMapWithTypeA.dhall
new file mode 100644
index 0000000..4245084
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/unit/ToMapWithTypeA.dhall
@@ -0,0 +1,16 @@
+{- This test verifies that the normalized result does not contain a type
+ annotation if the input record is non-empty.
+
+ The reason for this test is that implementations might need to store
+ optional type annotations for both `toMap` invocations and empty list
+ literals. If an implementation does so, a common mistake is to take
+ the optional type annotation and always pass it through as the optional
+ type annotation for the list literal that `toMap` generates.
+
+ However, the standard specifies that `toMap` should only generate a
+ type annotation if the input record is empty. If the input record is
+ non-empty then the resulting normalized list is non-empty and therefore
+ should not have a type annotation (since a non-empty list with a type
+ annotation is not in normal form).
+-}
+toMap { foo= 1, bar= 4, baz= 9 } : List { mapKey : Text, mapValue : Natural }
diff --git a/dhall-lang/tests/normalization/success/unit/ToMapWithTypeB.dhall b/dhall-lang/tests/normalization/success/unit/ToMapWithTypeB.dhall
new file mode 100644
index 0000000..e1e0b20
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/unit/ToMapWithTypeB.dhall
@@ -0,0 +1,4 @@
+[ { mapKey = "bar", mapValue = 4 }
+, { mapKey = "baz", mapValue = 9 }
+, { mapKey = "foo", mapValue = 1 }
+]
diff --git a/dhall-lang/tests/parser/failure/nonCharacter.dhall b/dhall-lang/tests/parser/failure/nonCharacter.dhall
new file mode 100644
index 0000000..9021a00
--- /dev/null
+++ b/dhall-lang/tests/parser/failure/nonCharacter.dhall
@@ -0,0 +1 @@
+"\u{10FFFF}"
diff --git a/dhall-lang/tests/parser/failure/nonUtf8.dhall b/dhall-lang/tests/parser/failure/nonUtf8.dhall
new file mode 100644
index 0000000..78ad55d
--- /dev/null
+++ b/dhall-lang/tests/parser/failure/nonUtf8.dhall
@@ -0,0 +1,4 @@
+{- This test verifies that an implementation correctly rejects non-UTF8
+ characters, such as this one: ""
+-}
+1
diff --git a/dhall-lang/tests/parser/failure/urlWithoutPath.dhall b/dhall-lang/tests/parser/failure/urlWithoutPath.dhall
deleted file mode 100644
index 0d7007f..0000000
--- a/dhall-lang/tests/parser/failure/urlWithoutPath.dhall
+++ /dev/null
@@ -1,2 +0,0 @@
--- See issue #205 for why this is not permitted
-http://example.com/
diff --git a/dhall-lang/tests/parser/success/annotationsA.dhall b/dhall-lang/tests/parser/success/annotationsA.dhall
index 5431972..0e5dc4e 100644
--- a/dhall-lang/tests/parser/success/annotationsA.dhall
+++ b/dhall-lang/tests/parser/success/annotationsA.dhall
@@ -1,4 +1 @@
-{ foo = ([] : List Natural) # [1, 2, 3] # ([1, 2, 3] : List Natural)
-, bar = [] : Optional Natural
-, baz = [1] : Optional Natural
-} : { foo : List Natural, bar : Optional Natural, baz : Optional Natural }
+([] : List Natural) # [ 1, 2, 3 ] # ([ 1, 2, 3 ] : List Natural) : List Natural
diff --git a/dhall-lang/tests/parser/success/annotationsB.dhallb b/dhall-lang/tests/parser/success/annotationsB.dhallb
index 68fbda7..a44e5fa 100644
--- a/dhall-lang/tests/parser/success/annotationsB.dhallb
+++ b/dhall-lang/tests/parser/success/annotationsB.dhallb
Binary files differ
diff --git a/dhall-lang/tests/parser/success/RecordProjectionByType.dhall b/dhall-lang/tests/parser/success/recordProjectionByExpressionA.dhall
index 4988e12..4988e12 100644
--- a/dhall-lang/tests/parser/success/RecordProjectionByType.dhall
+++ b/dhall-lang/tests/parser/success/recordProjectionByExpressionA.dhall
diff --git a/dhall-lang/tests/parser/success/recordProjectionByExpressionB.dhallb b/dhall-lang/tests/parser/success/recordProjectionByExpressionB.dhallb
new file mode 100644
index 0000000..0b822ea
--- /dev/null
+++ b/dhall-lang/tests/parser/success/recordProjectionByExpressionB.dhallb
Binary files differ
diff --git a/dhall-lang/tests/parser/success/text/escapedDoubleQuotedStringA.dhall b/dhall-lang/tests/parser/success/text/escapedDoubleQuotedStringA.dhall
index a8d0b9a..ab14b1a 100644
--- a/dhall-lang/tests/parser/success/text/escapedDoubleQuotedStringA.dhall
+++ b/dhall-lang/tests/parser/success/text/escapedDoubleQuotedStringA.dhall
@@ -1 +1 @@
-"\\\"\$\\\/\b\f\n\r\t \u2200(a : Type) \u2192 a"
+"\\\"\$\\\/\b\f\n\r\t\u{1D11E} \u2200(a : Type) \u2192 a"
diff --git a/dhall-lang/tests/parser/success/text/escapedDoubleQuotedStringB.dhallb b/dhall-lang/tests/parser/success/text/escapedDoubleQuotedStringB.dhallb
index 66b5eb5..d91f62c 100644
--- a/dhall-lang/tests/parser/success/text/escapedDoubleQuotedStringB.dhallb
+++ b/dhall-lang/tests/parser/success/text/escapedDoubleQuotedStringB.dhallb
@@ -1,2 +1,2 @@
-x\"$\/
- ∀(a : Type) → a \ No newline at end of file
+x"\"$\/
+ 𝄞 ∀(a : Type) → a \ No newline at end of file
diff --git a/dhall-lang/tests/parser/success/toMapA.dhall b/dhall-lang/tests/parser/success/toMapA.dhall
new file mode 100644
index 0000000..5353bf3
--- /dev/null
+++ b/dhall-lang/tests/parser/success/toMapA.dhall
@@ -0,0 +1 @@
+toMap { foo= 1, bar= 4, baz= 9 }
diff --git a/dhall-lang/tests/parser/success/toMapB.dhallb b/dhall-lang/tests/parser/success/toMapB.dhallb
new file mode 100644
index 0000000..963058d
--- /dev/null
+++ b/dhall-lang/tests/parser/success/toMapB.dhallb
@@ -0,0 +1 @@
+cbarcbaz cfoo \ No newline at end of file
diff --git a/dhall-lang/tests/parser/success/unit/ListLitEmptyA.dhall b/dhall-lang/tests/parser/success/unit/ListLitEmpty1A.dhall
index cbd438b..cbd438b 100644
--- a/dhall-lang/tests/parser/success/unit/ListLitEmptyA.dhall
+++ b/dhall-lang/tests/parser/success/unit/ListLitEmpty1A.dhall
diff --git a/dhall-lang/tests/parser/success/unit/ListLitEmptyB.dhallb b/dhall-lang/tests/parser/success/unit/ListLitEmpty1B.dhallb
index 856e56b..856e56b 100644
--- a/dhall-lang/tests/parser/success/unit/ListLitEmptyB.dhallb
+++ b/dhall-lang/tests/parser/success/unit/ListLitEmpty1B.dhallb
Binary files differ
diff --git a/dhall-lang/tests/parser/success/unit/ListLitEmpty2A.dhall b/dhall-lang/tests/parser/success/unit/ListLitEmpty2A.dhall
new file mode 100644
index 0000000..292df74
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/ListLitEmpty2A.dhall
@@ -0,0 +1 @@
+[] : T
diff --git a/dhall-lang/tests/parser/success/unit/ListLitEmpty2B.dhallb b/dhall-lang/tests/parser/success/unit/ListLitEmpty2B.dhallb
new file mode 100644
index 0000000..cbabb32
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/ListLitEmpty2B.dhallb
Binary files differ
diff --git a/dhall-lang/tests/parser/success/unit/ListLitEmptyPrecedenceA.dhall b/dhall-lang/tests/parser/success/unit/ListLitEmptyPrecedenceA.dhall
new file mode 100644
index 0000000..74149c2
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/ListLitEmptyPrecedenceA.dhall
@@ -0,0 +1 @@
+[] : List T U
diff --git a/dhall-lang/tests/parser/success/unit/ListLitEmptyPrecedenceB.dhallb b/dhall-lang/tests/parser/success/unit/ListLitEmptyPrecedenceB.dhallb
new file mode 100644
index 0000000..7f87abf
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/ListLitEmptyPrecedenceB.dhallb
Binary files differ
diff --git a/dhall-lang/tests/parser/success/unit/RecordFieldAccessA.dhall b/dhall-lang/tests/parser/success/unit/RecordFieldAccessA.dhall
new file mode 100644
index 0000000..48c5f00
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/RecordFieldAccessA.dhall
@@ -0,0 +1 @@
+r.x
diff --git a/dhall-lang/tests/parser/success/unit/RecordFieldAccessB.dhallb b/dhall-lang/tests/parser/success/unit/RecordFieldAccessB.dhallb
new file mode 100644
index 0000000..319b388
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/RecordFieldAccessB.dhallb
Binary files differ
diff --git a/dhall-lang/tests/parser/success/unit/RecordProjectFieldsA.dhall b/dhall-lang/tests/parser/success/unit/RecordProjectFieldsA.dhall
new file mode 100644
index 0000000..ea86639
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/RecordProjectFieldsA.dhall
@@ -0,0 +1 @@
+r.{ x, y, z }
diff --git a/dhall-lang/tests/parser/success/unit/RecordProjectFieldsB.dhallb b/dhall-lang/tests/parser/success/unit/RecordProjectFieldsB.dhallb
new file mode 100644
index 0000000..46cea17
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/RecordProjectFieldsB.dhallb
Binary files differ
diff --git a/dhall-lang/tests/parser/success/unit/RecordProjectionByTypeA.dhall b/dhall-lang/tests/parser/success/unit/RecordProjectionByTypeA.dhall
new file mode 100644
index 0000000..b083b0c
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/RecordProjectionByTypeA.dhall
@@ -0,0 +1 @@
+{ a = 1, b = 2 }.({ a : Natural })
diff --git a/dhall-lang/tests/parser/success/unit/RecordProjectionByTypeB.dhallb b/dhall-lang/tests/parser/success/unit/RecordProjectionByTypeB.dhallb
new file mode 100644
index 0000000..51de1f5
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/RecordProjectionByTypeB.dhallb
@@ -0,0 +1,2 @@
+
+aaabaagNatural \ No newline at end of file
diff --git a/dhall-lang/tests/parser/success/unit/RecordProjectionByTypeEmptyA.dhall b/dhall-lang/tests/parser/success/unit/RecordProjectionByTypeEmptyA.dhall
new file mode 100644
index 0000000..44150df
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/RecordProjectionByTypeEmptyA.dhall
@@ -0,0 +1 @@
+{ a = 1, b = 2 }.({})
diff --git a/dhall-lang/tests/parser/success/unit/RecordProjectionByTypeEmptyB.dhallb b/dhall-lang/tests/parser/success/unit/RecordProjectionByTypeEmptyB.dhallb
new file mode 100644
index 0000000..661e12c
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/RecordProjectionByTypeEmptyB.dhallb
@@ -0,0 +1,2 @@
+
+aaab \ No newline at end of file
diff --git a/dhall-lang/tests/parser/success/unit/import/asLocationA.dhall b/dhall-lang/tests/parser/success/unit/import/asLocationA.dhall
new file mode 100644
index 0000000..35f2138
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/asLocationA.dhall
@@ -0,0 +1,6 @@
+{ _1 = ./some/import.dhall as Location
+, _2 = /absolute/import sha256:f9340badf94a684e652e0a384f64363293d8b632d971f3453f7ee22f10ab6e75 as Location
+, _3 = https://prelude.dhall-lang.org/package.dhall as Location
+, _4 = env:HOME as Location
+, _5 = missing as Location
+}
diff --git a/dhall-lang/tests/parser/success/unit/import/asLocationB.dhallb b/dhall-lang/tests/parser/success/unit/import/asLocationB.dhallb
new file mode 100644
index 0000000..15e9066
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/asLocationB.dhallb
@@ -0,0 +1,2 @@
+b_1dsomelimport.dhallb_2X" 4 JhNe.
+8Od62ض2qE?~/nuhabsolutefimportb_3vprelude.dhall-lang.orgmpackage.dhallb_4dHOMEb_5 \ No newline at end of file
diff --git a/dhall-lang/tests/parser/success/unit/import/inlineUsingA.dhall b/dhall-lang/tests/parser/success/unit/import/inlineUsingA.dhall
index c2eeaa8..6589163 100644
--- a/dhall-lang/tests/parser/success/unit/import/inlineUsingA.dhall
+++ b/dhall-lang/tests/parser/success/unit/import/inlineUsingA.dhall
@@ -8,7 +8,7 @@
-}
https://example.com/foo using
- [ { header = "Authorization"
- , value = "token 5199831f4dd3b79e7c5b7e0ebe75d67aa66e79d4"
+ [ { mapKey = "Authorization"
+ , mapValue = "token 5199831f4dd3b79e7c5b7e0ebe75d67aa66e79d4"
}
]
diff --git a/dhall-lang/tests/parser/success/unit/import/inlineUsingB.dhallb b/dhall-lang/tests/parser/success/unit/import/inlineUsingB.dhallb
index 3f50d53..9de0250 100644
--- a/dhall-lang/tests/parser/success/unit/import/inlineUsingB.dhallb
+++ b/dhall-lang/tests/parser/success/unit/import/inlineUsingB.dhallb
Binary files differ
diff --git a/dhall-lang/tests/parser/success/unit/import/parenthesizeUsingB.dhallb b/dhall-lang/tests/parser/success/unit/import/parenthesizeUsingB.dhallb
index 7ba5ad7..d05cfd1 100644
--- a/dhall-lang/tests/parser/success/unit/import/parenthesizeUsingB.dhallb
+++ b/dhall-lang/tests/parser/success/unit/import/parenthesizeUsingB.dhallb
Binary files differ
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/basicHttpA.dhall b/dhall-lang/tests/parser/success/unit/import/urls/basicHttpA.dhall
new file mode 100644
index 0000000..cf5ddf7
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/basicHttpA.dhall
@@ -0,0 +1 @@
+http://example.com/someFile.dhall
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/basicHttpB.dhallb b/dhall-lang/tests/parser/success/unit/import/urls/basicHttpB.dhallb
new file mode 100644
index 0000000..6fe3059
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/basicHttpB.dhallb
Binary files differ
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/basicHttpsA.dhall b/dhall-lang/tests/parser/success/unit/import/urls/basicHttpsA.dhall
new file mode 100644
index 0000000..009061c
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/basicHttpsA.dhall
@@ -0,0 +1 @@
+https://raw.githubusercontent.com/dhall-lang/dhall-haskell/18e4e9a18dc53271146df3ccf5b4177c3552236b/examples/True
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/basicHttpsB.dhallb b/dhall-lang/tests/parser/success/unit/import/urls/basicHttpsB.dhallb
new file mode 100644
index 0000000..7ed2dee
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/basicHttpsB.dhallb
Binary files differ
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/emptyPath0A.dhall b/dhall-lang/tests/parser/success/unit/import/urls/emptyPath0A.dhall
new file mode 100644
index 0000000..52eb867
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/emptyPath0A.dhall
@@ -0,0 +1,3 @@
+-- the normal form for an empty path is a path of `/`
+-- see RFC7230 section 2.7.3
+https://example.com
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/emptyPath0B.dhallb b/dhall-lang/tests/parser/success/unit/import/urls/emptyPath0B.dhallb
new file mode 100644
index 0000000..1321643
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/emptyPath0B.dhallb
Binary files differ
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/emptyPath1A.dhall b/dhall-lang/tests/parser/success/unit/import/urls/emptyPath1A.dhall
new file mode 100644
index 0000000..dc54b2a
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/emptyPath1A.dhall
@@ -0,0 +1 @@
+https://example.com/
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/emptyPath1B.dhallb b/dhall-lang/tests/parser/success/unit/import/urls/emptyPath1B.dhallb
new file mode 100644
index 0000000..1321643
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/emptyPath1B.dhallb
Binary files differ
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/emptyPathSegmentA.dhall b/dhall-lang/tests/parser/success/unit/import/urls/emptyPathSegmentA.dhall
new file mode 100644
index 0000000..ba8e6ad
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/emptyPathSegmentA.dhall
@@ -0,0 +1,2 @@
+-- empty path segments are not equivalent to missing path segments
+https://example.com/foo//bar
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/emptyPathSegmentB.dhallb b/dhall-lang/tests/parser/success/unit/import/urls/emptyPathSegmentB.dhallb
new file mode 100644
index 0000000..4c9fc6d
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/emptyPathSegmentB.dhallb
Binary files differ
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/emptyQueryA.dhall b/dhall-lang/tests/parser/success/unit/import/urls/emptyQueryA.dhall
new file mode 100644
index 0000000..12b9030
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/emptyQueryA.dhall
@@ -0,0 +1,3 @@
+-- an empty query string is not the same as a missing one
+-- see RFC 3986 section 6.2.3
+https://example.com/foo?
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/emptyQueryB.dhallb b/dhall-lang/tests/parser/success/unit/import/urls/emptyQueryB.dhallb
new file mode 100644
index 0000000..916660f
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/emptyQueryB.dhallb
Binary files differ
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/escapedPathA.dhall b/dhall-lang/tests/parser/success/unit/import/urls/escapedPathA.dhall
new file mode 100644
index 0000000..c8108a7
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/escapedPathA.dhall
@@ -0,0 +1 @@
+https://example.com/a%20b/c%2fd/e+f
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/escapedPathB.dhallb b/dhall-lang/tests/parser/success/unit/import/urls/escapedPathB.dhallb
new file mode 100644
index 0000000..c988f57
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/escapedPathB.dhallb
Binary files differ
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/escapedQueryA.dhall b/dhall-lang/tests/parser/success/unit/import/urls/escapedQueryA.dhall
new file mode 100644
index 0000000..fb9bdc9
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/escapedQueryA.dhall
@@ -0,0 +1,2 @@
+-- Unlike paths, query strings should *not* be decoded
+https://example.com/foo?a%20b=c%2fd&e+f/?
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/escapedQueryB.dhallb b/dhall-lang/tests/parser/success/unit/import/urls/escapedQueryB.dhallb
new file mode 100644
index 0000000..eff7a6e
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/escapedQueryB.dhallb
Binary files differ
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/fragmentParsesAsListAppendA.dhall b/dhall-lang/tests/parser/success/unit/import/urls/fragmentParsesAsListAppendA.dhall
new file mode 100644
index 0000000..051a7ae
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/fragmentParsesAsListAppendA.dhall
@@ -0,0 +1,11 @@
+{- Fragment identifiers are not allowed in URLs because they serve no purpose
+ for Dhall and they could lead to ambiguity if a parser interprets them as
+ the list append operator (`#`)
+
+ The following expression therefore only has one valid parse, which is to
+ interpret the `#` as a list append. In other words, the following expression
+ is parsed as:
+
+ (https://example.com/foo) # bar
+-}
+https://example.com/foo#bar
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/fragmentParsesAsListAppendB.dhallb b/dhall-lang/tests/parser/success/unit/import/urls/fragmentParsesAsListAppendB.dhallb
new file mode 100644
index 0000000..29b6832
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/fragmentParsesAsListAppendB.dhallb
Binary files differ
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/ipv4A.dhall b/dhall-lang/tests/parser/success/unit/import/urls/ipv4A.dhall
new file mode 100644
index 0000000..68f3114
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/ipv4A.dhall
@@ -0,0 +1 @@
+https://127.0.0.1/index.dhall
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/ipv4B.dhallb b/dhall-lang/tests/parser/success/unit/import/urls/ipv4B.dhallb
new file mode 100644
index 0000000..564c888
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/ipv4B.dhallb
Binary files differ
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/ipv6longA.dhall b/dhall-lang/tests/parser/success/unit/import/urls/ipv6longA.dhall
new file mode 100644
index 0000000..4cf06bc
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/ipv6longA.dhall
@@ -0,0 +1 @@
+https://[2001:db8:85a3:0:0:8a2e:370:7334]/tutorial.dhall
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/ipv6longB.dhallb b/dhall-lang/tests/parser/success/unit/import/urls/ipv6longB.dhallb
new file mode 100644
index 0000000..e8c35f5
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/ipv6longB.dhallb
Binary files differ
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/ipv6mediumA.dhall b/dhall-lang/tests/parser/success/unit/import/urls/ipv6mediumA.dhall
new file mode 100644
index 0000000..0f877e6
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/ipv6mediumA.dhall
@@ -0,0 +1 @@
+https://[2001:db8:85a3::8a2e:370:7334]/tutorial.dhall
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/ipv6mediumB.dhallb b/dhall-lang/tests/parser/success/unit/import/urls/ipv6mediumB.dhallb
new file mode 100644
index 0000000..6d7ec43
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/ipv6mediumB.dhallb
Binary files differ
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/ipv6shortA.dhall b/dhall-lang/tests/parser/success/unit/import/urls/ipv6shortA.dhall
new file mode 100644
index 0000000..2d30f9d
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/ipv6shortA.dhall
@@ -0,0 +1 @@
+https://[::]/index.dhall
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/ipv6shortB.dhallb b/dhall-lang/tests/parser/success/unit/import/urls/ipv6shortB.dhallb
new file mode 100644
index 0000000..44ac083
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/ipv6shortB.dhallb
Binary files differ
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/ipv6withipv4A.dhall b/dhall-lang/tests/parser/success/unit/import/urls/ipv6withipv4A.dhall
new file mode 100644
index 0000000..e8bc016
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/ipv6withipv4A.dhall
@@ -0,0 +1 @@
+https://[2001:db8:85a3::8a2e:3.112.115.52]/tutorial.dhall
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/ipv6withipv4B.dhallb b/dhall-lang/tests/parser/success/unit/import/urls/ipv6withipv4B.dhallb
new file mode 100644
index 0000000..f30c3c4
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/ipv6withipv4B.dhallb
Binary files differ
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/portA.dhall b/dhall-lang/tests/parser/success/unit/import/urls/portA.dhall
new file mode 100644
index 0000000..84dfbeb
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/portA.dhall
@@ -0,0 +1 @@
+https://example.com:1234/foo
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/portB.dhallb b/dhall-lang/tests/parser/success/unit/import/urls/portB.dhallb
new file mode 100644
index 0000000..0c29fe5
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/portB.dhallb
Binary files differ
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/potPourriA.dhall b/dhall-lang/tests/parser/success/unit/import/urls/potPourriA.dhall
new file mode 100644
index 0000000..4de1b98
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/potPourriA.dhall
@@ -0,0 +1 @@
+https://-._~%2C!$&'*+;=:@0abc1--12a------a-a--a-0/foo?/-._~%2C!$&'*+;=:@/?
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/potPourriB.dhallb b/dhall-lang/tests/parser/success/unit/import/urls/potPourriB.dhallb
new file mode 100644
index 0000000..fd43a16
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/potPourriB.dhallb
Binary files differ
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/quotedPathFakeUrlEncodeA.dhall b/dhall-lang/tests/parser/success/unit/import/urls/quotedPathFakeUrlEncodeA.dhall
new file mode 100644
index 0000000..38da32f
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/quotedPathFakeUrlEncodeA.dhall
@@ -0,0 +1 @@
+https://example.com/"a%20b"/c
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/quotedPathFakeUrlEncodeB.dhallb b/dhall-lang/tests/parser/success/unit/import/urls/quotedPathFakeUrlEncodeB.dhallb
new file mode 100644
index 0000000..bc16a2a
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/quotedPathFakeUrlEncodeB.dhallb
Binary files differ
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/userinfoA.dhall b/dhall-lang/tests/parser/success/unit/import/urls/userinfoA.dhall
new file mode 100644
index 0000000..7de045e
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/userinfoA.dhall
@@ -0,0 +1 @@
+https://john:doe@example.com/foo
diff --git a/dhall-lang/tests/parser/success/unit/import/urls/userinfoB.dhallb b/dhall-lang/tests/parser/success/unit/import/urls/userinfoB.dhallb
new file mode 100644
index 0000000..5100743
--- /dev/null
+++ b/dhall-lang/tests/parser/success/unit/import/urls/userinfoB.dhallb
Binary files differ
diff --git a/dhall-lang/tests/semantic-hash/success/haskell-tutorial/access/0A.dhall b/dhall-lang/tests/semantic-hash/success/haskell-tutorial/access/0A.dhall
new file mode 100644
index 0000000..bc4f58e
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/haskell-tutorial/access/0A.dhall
@@ -0,0 +1 @@
+{ x = "foo" }.x
diff --git a/dhall-lang/tests/semantic-hash/success/haskell-tutorial/access/0B.hash b/dhall-lang/tests/semantic-hash/success/haskell-tutorial/access/0B.hash
new file mode 100644
index 0000000..103d73c
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/haskell-tutorial/access/0B.hash
@@ -0,0 +1 @@
+sha256:fd881e3d48cbc85b4044697bdce8167a77f3fb4665ff0b647a1210a17528818a
diff --git a/dhall-lang/tests/semantic-hash/success/haskell-tutorial/access/1A.dhall b/dhall-lang/tests/semantic-hash/success/haskell-tutorial/access/1A.dhall
new file mode 100644
index 0000000..014d7df
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/haskell-tutorial/access/1A.dhall
@@ -0,0 +1 @@
+< Foo : Text | Bar : Natural >.Foo
diff --git a/dhall-lang/tests/semantic-hash/success/haskell-tutorial/access/1B.hash b/dhall-lang/tests/semantic-hash/success/haskell-tutorial/access/1B.hash
new file mode 100644
index 0000000..223779b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/haskell-tutorial/access/1B.hash
@@ -0,0 +1 @@
+sha256:35ba8bddad36acfb29cc6f1700364544c145e96cf522f592f18f90c2f96e6e9c
diff --git a/dhall-lang/tests/semantic-hash/success/haskell-tutorial/combineTypes/0A.dhall b/dhall-lang/tests/semantic-hash/success/haskell-tutorial/combineTypes/0A.dhall
new file mode 100644
index 0000000..1ce308e
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/haskell-tutorial/combineTypes/0A.dhall
@@ -0,0 +1 @@
+{ foo : { bar : Text } } ⩓ { foo : { baz : Bool }, qux : Integer }
diff --git a/dhall-lang/tests/semantic-hash/success/haskell-tutorial/combineTypes/0B.hash b/dhall-lang/tests/semantic-hash/success/haskell-tutorial/combineTypes/0B.hash
new file mode 100644
index 0000000..84f7b47
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/haskell-tutorial/combineTypes/0B.hash
@@ -0,0 +1 @@
+sha256:4495bbf3fea6c579c65ee51463b225747803b94668013528b9ca0384304cb350
diff --git a/dhall-lang/tests/semantic-hash/success/haskell-tutorial/combineTypes/1A.dhall b/dhall-lang/tests/semantic-hash/success/haskell-tutorial/combineTypes/1A.dhall
new file mode 100644
index 0000000..4c881a4
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/haskell-tutorial/combineTypes/1A.dhall
@@ -0,0 +1 @@
+{ foo : { bar : Text } } //\\ { foo : { baz : Bool }, qux : Integer }
diff --git a/dhall-lang/tests/semantic-hash/success/haskell-tutorial/combineTypes/1B.hash b/dhall-lang/tests/semantic-hash/success/haskell-tutorial/combineTypes/1B.hash
new file mode 100644
index 0000000..84f7b47
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/haskell-tutorial/combineTypes/1B.hash
@@ -0,0 +1 @@
+sha256:4495bbf3fea6c579c65ee51463b225747803b94668013528b9ca0384304cb350
diff --git a/dhall-lang/tests/semantic-hash/success/haskell-tutorial/prefer/0A.dhall b/dhall-lang/tests/semantic-hash/success/haskell-tutorial/prefer/0A.dhall
new file mode 100644
index 0000000..e078ccc
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/haskell-tutorial/prefer/0A.dhall
@@ -0,0 +1 @@
+{ foo = 1, bar = "ABC" } // { baz = True }
diff --git a/dhall-lang/tests/semantic-hash/success/haskell-tutorial/prefer/0B.hash b/dhall-lang/tests/semantic-hash/success/haskell-tutorial/prefer/0B.hash
new file mode 100644
index 0000000..420bd31
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/haskell-tutorial/prefer/0B.hash
@@ -0,0 +1 @@
+sha256:18fbad84131d28b6d412e6bc09d5ee8eaf432b639c6cc6f1bef1b4ef366642d7
diff --git a/dhall-lang/tests/semantic-hash/success/haskell-tutorial/projection/0A.dhall b/dhall-lang/tests/semantic-hash/success/haskell-tutorial/projection/0A.dhall
new file mode 100644
index 0000000..18f9b45
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/haskell-tutorial/projection/0A.dhall
@@ -0,0 +1 @@
+{ x = 1, y = True, z = "ABC" }.{ x, y }
diff --git a/dhall-lang/tests/semantic-hash/success/haskell-tutorial/projection/0B.hash b/dhall-lang/tests/semantic-hash/success/haskell-tutorial/projection/0B.hash
new file mode 100644
index 0000000..2fd4632
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/haskell-tutorial/projection/0B.hash
@@ -0,0 +1 @@
+sha256:b7ae500723633be94b53b905384236fcd18cbce59314bb51044bb7d3f3939e6e
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/and/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Bool/and/0A.dhall
new file mode 100644
index 0000000..0413128
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/and/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Bool/and [ True, False, True ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/and/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Bool/and/0B.hash
new file mode 100644
index 0000000..e88d95b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/and/0B.hash
@@ -0,0 +1 @@
+sha256:2017ff3461395672aa0aa4f64894fd2f95a4b120e2690e8951656d79adc2eed2
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/and/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Bool/and/1A.dhall
new file mode 100644
index 0000000..8b2ecd7
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/and/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Bool/and ([] : List Bool)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/and/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Bool/and/1B.hash
new file mode 100644
index 0000000..738b376
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/and/1B.hash
@@ -0,0 +1 @@
+sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/build/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Bool/build/0A.dhall
new file mode 100644
index 0000000..2bafd15
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/build/0A.dhall
@@ -0,0 +1,2 @@
+../../../../../../Prelude/Bool/build
+(λ(bool : Type) → λ(true : bool) → λ(false : bool) → true)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/build/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Bool/build/0B.hash
new file mode 100644
index 0000000..738b376
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/build/0B.hash
@@ -0,0 +1 @@
+sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/build/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Bool/build/1A.dhall
new file mode 100644
index 0000000..06fe8bb
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/build/1A.dhall
@@ -0,0 +1,2 @@
+../../../../../../Prelude/Bool/build
+(λ(bool : Type) → λ(true : bool) → λ(false : bool) → false)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/build/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Bool/build/1B.hash
new file mode 100644
index 0000000..e88d95b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/build/1B.hash
@@ -0,0 +1 @@
+sha256:2017ff3461395672aa0aa4f64894fd2f95a4b120e2690e8951656d79adc2eed2
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/even/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Bool/even/0A.dhall
new file mode 100644
index 0000000..824411e
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/even/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Bool/even [ False, True, False ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/even/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Bool/even/0B.hash
new file mode 100644
index 0000000..738b376
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/even/0B.hash
@@ -0,0 +1 @@
+sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/even/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Bool/even/1A.dhall
new file mode 100644
index 0000000..cbb0149
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/even/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Bool/even [ False, True ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/even/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Bool/even/1B.hash
new file mode 100644
index 0000000..e88d95b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/even/1B.hash
@@ -0,0 +1 @@
+sha256:2017ff3461395672aa0aa4f64894fd2f95a4b120e2690e8951656d79adc2eed2
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/even/2A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Bool/even/2A.dhall
new file mode 100644
index 0000000..8de55bb
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/even/2A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Bool/even [ False ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/even/2B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Bool/even/2B.hash
new file mode 100644
index 0000000..e88d95b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/even/2B.hash
@@ -0,0 +1 @@
+sha256:2017ff3461395672aa0aa4f64894fd2f95a4b120e2690e8951656d79adc2eed2
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/even/3A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Bool/even/3A.dhall
new file mode 100644
index 0000000..8f4617e
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/even/3A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Bool/even ([] : List Bool)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/even/3B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Bool/even/3B.hash
new file mode 100644
index 0000000..738b376
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/even/3B.hash
@@ -0,0 +1 @@
+sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/fold/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Bool/fold/0A.dhall
new file mode 100644
index 0000000..b619908
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/fold/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Bool/fold True Natural 0 1
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/fold/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Bool/fold/0B.hash
new file mode 100644
index 0000000..b175d49
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/fold/0B.hash
@@ -0,0 +1 @@
+sha256:d0a48d41dcc572839faa9499b6c316b8d0d7115efac2ac770f062cd5fd6d0181
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/fold/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Bool/fold/1A.dhall
new file mode 100644
index 0000000..1e1582b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/fold/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Bool/fold False Natural 0 1
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/fold/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Bool/fold/1B.hash
new file mode 100644
index 0000000..ae27037
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/fold/1B.hash
@@ -0,0 +1 @@
+sha256:d60d8415e36e86dae7f42933d3b0c4fe3ca238f057fba206c7e9fbf5d784fe15
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/not/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Bool/not/0A.dhall
new file mode 100644
index 0000000..05bdcd1
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/not/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Bool/not True
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/not/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Bool/not/0B.hash
new file mode 100644
index 0000000..e88d95b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/not/0B.hash
@@ -0,0 +1 @@
+sha256:2017ff3461395672aa0aa4f64894fd2f95a4b120e2690e8951656d79adc2eed2
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/not/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Bool/not/1A.dhall
new file mode 100644
index 0000000..44ed28c
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/not/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Bool/not False
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/not/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Bool/not/1B.hash
new file mode 100644
index 0000000..738b376
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/not/1B.hash
@@ -0,0 +1 @@
+sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/0A.dhall
new file mode 100644
index 0000000..4ae9a9f
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Bool/odd [ True, False, True ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/0B.hash
new file mode 100644
index 0000000..e88d95b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/0B.hash
@@ -0,0 +1 @@
+sha256:2017ff3461395672aa0aa4f64894fd2f95a4b120e2690e8951656d79adc2eed2
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/1A.dhall
new file mode 100644
index 0000000..290eca2
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Bool/odd [ True, False ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/1B.hash
new file mode 100644
index 0000000..738b376
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/1B.hash
@@ -0,0 +1 @@
+sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/2A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/2A.dhall
new file mode 100644
index 0000000..bf18dcb
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/2A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Bool/odd [ True ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/2B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/2B.hash
new file mode 100644
index 0000000..738b376
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/2B.hash
@@ -0,0 +1 @@
+sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/3A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/3A.dhall
new file mode 100644
index 0000000..666ae4e
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/3A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Bool/odd ([] : List Bool)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/3B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/3B.hash
new file mode 100644
index 0000000..e88d95b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/3B.hash
@@ -0,0 +1 @@
+sha256:2017ff3461395672aa0aa4f64894fd2f95a4b120e2690e8951656d79adc2eed2
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/or/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Bool/or/0A.dhall
new file mode 100644
index 0000000..5cfc69a
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/or/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Bool/or [ True, False, True ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/or/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Bool/or/0B.hash
new file mode 100644
index 0000000..738b376
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/or/0B.hash
@@ -0,0 +1 @@
+sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/or/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Bool/or/1A.dhall
new file mode 100644
index 0000000..fa765f1
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/or/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Bool/or ([] : List Bool)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/or/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Bool/or/1B.hash
new file mode 100644
index 0000000..e88d95b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/or/1B.hash
@@ -0,0 +1 @@
+sha256:2017ff3461395672aa0aa4f64894fd2f95a4b120e2690e8951656d79adc2eed2
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/show/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Bool/show/0A.dhall
new file mode 100644
index 0000000..e4278c1
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/show/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Bool/show True
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/show/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Bool/show/0B.hash
new file mode 100644
index 0000000..004715d
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/show/0B.hash
@@ -0,0 +1 @@
+sha256:cdbb7fd982ba05e709fe67b23818fffb65ff9c0b8abde1abb5ac1a8245891a3f
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/show/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Bool/show/1A.dhall
new file mode 100644
index 0000000..2c52d3c
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/show/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Bool/show False
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Bool/show/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Bool/show/1B.hash
new file mode 100644
index 0000000..cbd5d23
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Bool/show/1B.hash
@@ -0,0 +1 @@
+sha256:2357bb42b56beb99180d967177c0490061bd3536a147dfe144d2630f983004e5
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Double/show/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Double/show/0A.dhall
new file mode 100644
index 0000000..6180950
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Double/show/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Double/show -3.1
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Double/show/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Double/show/0B.hash
new file mode 100644
index 0000000..2f50782
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Double/show/0B.hash
@@ -0,0 +1 @@
+sha256:d0b3cdb4f3cd5375495629450de676f445c0da6980a5ada251df199079d0ef89
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Double/show/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Double/show/1A.dhall
new file mode 100644
index 0000000..94881b4
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Double/show/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Double/show 0.4
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Double/show/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Double/show/1B.hash
new file mode 100644
index 0000000..450b78b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Double/show/1B.hash
@@ -0,0 +1 @@
+sha256:dd5e8756d06f12ef6e003dc769b6e1222e5aa0c8491579dc65b2dd6f4f0ec53d
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Integer/show/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Integer/show/0A.dhall
new file mode 100644
index 0000000..dc6dd4e
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Integer/show/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Integer/show -3
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Integer/show/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Integer/show/0B.hash
new file mode 100644
index 0000000..9d79ade
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Integer/show/0B.hash
@@ -0,0 +1 @@
+sha256:053de6c2b7f281dd82dd9b643cc848e64633b88c9c57082ec0ac41257c5592d7
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Integer/show/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Integer/show/1A.dhall
new file mode 100644
index 0000000..29d4706
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Integer/show/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Integer/show +0
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Integer/show/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Integer/show/1B.hash
new file mode 100644
index 0000000..f206c9d
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Integer/show/1B.hash
@@ -0,0 +1 @@
+sha256:4ab1c5aa262f39cdbe1f4924accb69bb44e2a616b5a0ca39655eebd0cc863d33
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Integer/toDouble/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Integer/toDouble/0A.dhall
new file mode 100644
index 0000000..d7aaa50
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Integer/toDouble/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Integer/toDouble -3
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Integer/toDouble/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Integer/toDouble/0B.hash
new file mode 100644
index 0000000..e215c30
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Integer/toDouble/0B.hash
@@ -0,0 +1 @@
+sha256:17bf67209e1b636613b9f97ca5f2b8a59fab70eaab65a029be19129ec5f444ad
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Integer/toDouble/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Integer/toDouble/1A.dhall
new file mode 100644
index 0000000..b19218b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Integer/toDouble/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Integer/toDouble +2
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Integer/toDouble/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Integer/toDouble/1B.hash
new file mode 100644
index 0000000..0553ccf
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Integer/toDouble/1B.hash
@@ -0,0 +1 @@
+sha256:d4b8848ff8a5d403469e4107f4a0cfdc42197bb3a9fcd2fa477b65dd252ce770
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/all/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/all/0A.dhall
new file mode 100644
index 0000000..6654e67
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/all/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/all Natural Natural/even [ 2, 3, 5 ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/all/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/all/0B.hash
new file mode 100644
index 0000000..e88d95b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/all/0B.hash
@@ -0,0 +1 @@
+sha256:2017ff3461395672aa0aa4f64894fd2f95a4b120e2690e8951656d79adc2eed2
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/all/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/all/1A.dhall
new file mode 100644
index 0000000..4e9d433
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/all/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/all Natural Natural/even ([] : List Natural)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/all/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/all/1B.hash
new file mode 100644
index 0000000..738b376
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/all/1B.hash
@@ -0,0 +1 @@
+sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/any/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/any/0A.dhall
new file mode 100644
index 0000000..9ca2b2a
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/any/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/any Natural Natural/even [ 2, 3, 5 ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/any/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/any/0B.hash
new file mode 100644
index 0000000..738b376
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/any/0B.hash
@@ -0,0 +1 @@
+sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/any/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/any/1A.dhall
new file mode 100644
index 0000000..0d4623e
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/any/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/any Natural Natural/even ([] : List Natural)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/any/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/any/1B.hash
new file mode 100644
index 0000000..e88d95b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/any/1B.hash
@@ -0,0 +1 @@
+sha256:2017ff3461395672aa0aa4f64894fd2f95a4b120e2690e8951656d79adc2eed2
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/build/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/build/0A.dhall
new file mode 100644
index 0000000..a2fc3a1
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/build/0A.dhall
@@ -0,0 +1,7 @@
+../../../../../../Prelude/List/build
+Text
+( λ(list : Type)
+→ λ(cons : Text → list → list)
+→ λ(nil : list)
+→ cons "ABC" (cons "DEF" nil)
+)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/build/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/build/0B.hash
new file mode 100644
index 0000000..5240aae
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/build/0B.hash
@@ -0,0 +1 @@
+sha256:8a08646db7447b14cf03a497635242b6fb76365017fc1699b2a8807272a2ec58
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/build/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/build/1A.dhall
new file mode 100644
index 0000000..dbd5abb
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/build/1A.dhall
@@ -0,0 +1,7 @@
+../../../../../../Prelude/List/build
+Text
+( λ(list : Type)
+→ λ(cons : Text → list → list)
+→ λ(nil : list)
+→ nil
+)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/build/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/build/1B.hash
new file mode 100644
index 0000000..dcade2c
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/build/1B.hash
@@ -0,0 +1 @@
+sha256:6da0c98142d1168ac9d6080b7853d2b59b97d42079e1b2f121daf449b3b2e449
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/concat/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/concat/0A.dhall
new file mode 100644
index 0000000..273615b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/concat/0A.dhall
@@ -0,0 +1,5 @@
+../../../../../../Prelude/List/concat Natural
+[ [ 0, 1, 2 ]
+, [ 3, 4 ]
+, [ 5, 6, 7, 8 ]
+]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/concat/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/concat/0B.hash
new file mode 100644
index 0000000..b4af4b8
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/concat/0B.hash
@@ -0,0 +1 @@
+sha256:ae3a399d05bafcee80c088ca6c740f0c61c2a4c6fce6d7e4f4fa26560eac083f
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/concat/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/concat/1A.dhall
new file mode 100644
index 0000000..1b9e4c9
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/concat/1A.dhall
@@ -0,0 +1,5 @@
+../../../../../../Prelude/List/concat Natural
+[ [] : List Natural
+, [] : List Natural
+, [] : List Natural
+]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/concat/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/concat/1B.hash
new file mode 100644
index 0000000..326cc5d
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/concat/1B.hash
@@ -0,0 +1 @@
+sha256:d79a2e0e14809ab2dbd2d180e60da8e129a5fb197bdd0caed57e3828402e48a9
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/concatMap/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/concatMap/0A.dhall
new file mode 100644
index 0000000..bc4a014
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/concatMap/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/concatMap Natural Natural (λ(n : Natural) → [ n, n ]) [ 2, 3, 5 ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/concatMap/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/concatMap/0B.hash
new file mode 100644
index 0000000..6e49fd1
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/concatMap/0B.hash
@@ -0,0 +1 @@
+sha256:ea1f5046bcba6efb41bde23738d9a3f3aa2cda3dc722999d9e4f477eb9d1b12d
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/concatMap/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/concatMap/1A.dhall
new file mode 100644
index 0000000..987b69f
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/concatMap/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/concatMap Natural Natural (λ(n : Natural) → [ n, n ]) ([] : List Natural)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/concatMap/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/concatMap/1B.hash
new file mode 100644
index 0000000..326cc5d
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/concatMap/1B.hash
@@ -0,0 +1 @@
+sha256:d79a2e0e14809ab2dbd2d180e60da8e129a5fb197bdd0caed57e3828402e48a9
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/filter/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/filter/0A.dhall
new file mode 100644
index 0000000..75c5007
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/filter/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/filter Natural Natural/even [ 2, 3, 5 ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/filter/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/filter/0B.hash
new file mode 100644
index 0000000..a8a1ec2
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/filter/0B.hash
@@ -0,0 +1 @@
+sha256:988afbf26d86e95a4e6b78b0c344c9f987dcd5f7d7a7c541601bb1e9a01c9102
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/filter/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/filter/1A.dhall
new file mode 100644
index 0000000..b4a6389
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/filter/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/filter Natural Natural/odd [ 2, 3, 5 ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/filter/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/filter/1B.hash
new file mode 100644
index 0000000..9c5a6a7
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/filter/1B.hash
@@ -0,0 +1 @@
+sha256:68248e1b69b249e6aeebcd36e7034f159b75d2931105fb4d41fc55d644b7ee8d
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/fold/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/fold/0A.dhall
new file mode 100644
index 0000000..9ab0bd2
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/fold/0A.dhall
@@ -0,0 +1,6 @@
+../../../../../../Prelude/List/fold
+Natural
+[ 2, 3, 5 ]
+Natural
+(λ(x : Natural) → λ(y : Natural) → x + y)
+0
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/fold/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/fold/0B.hash
new file mode 100644
index 0000000..ed551fb
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/fold/0B.hash
@@ -0,0 +1 @@
+sha256:d4428061b6fd69b6b45574603ac71060f9756a5c9a1642df322812e3a7ea858b
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/fold/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/fold/1A.dhall
new file mode 100644
index 0000000..8ff1657
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/fold/1A.dhall
@@ -0,0 +1,7 @@
+ λ(nil : Natural)
+→ ../../../../../../Prelude/List/fold
+ Natural
+ [ 2, 3, 5 ]
+ Natural
+ (λ(x : Natural) → λ(y : Natural) → x + y)
+ nil
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/fold/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/fold/1B.hash
new file mode 100644
index 0000000..fddbe2c
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/fold/1B.hash
@@ -0,0 +1 @@
+sha256:3bd732ae873cb107c3dfef4ae953f6480af310b27fda6b678b43569841e1012b
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/fold/2A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/fold/2A.dhall
new file mode 100644
index 0000000..04f2868
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/fold/2A.dhall
@@ -0,0 +1,4 @@
+ λ(list : Type)
+→ λ(cons : Natural → list → list)
+→ λ(nil : list)
+→ ../../../../../../Prelude/List/fold Natural [ 2, 3, 5 ] list cons nil
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/fold/2B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/fold/2B.hash
new file mode 100644
index 0000000..931d8db
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/fold/2B.hash
@@ -0,0 +1 @@
+sha256:186c485f65cbbf97aba127a1205a16ee1125ec279e727ff05d8f8ada624257c7
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/generate/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/generate/0A.dhall
new file mode 100644
index 0000000..6064aa3
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/generate/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/generate 5 Bool Natural/even
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/generate/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/generate/0B.hash
new file mode 100644
index 0000000..b3b987c
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/generate/0B.hash
@@ -0,0 +1 @@
+sha256:0860d18cdc28bc4e7b081bf8c9891ab07e303e4f72b3439bb3a92d7dedd7e8fa
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/generate/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/generate/1A.dhall
new file mode 100644
index 0000000..5c13b2a
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/generate/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/generate 0 Bool Natural/even
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/generate/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/generate/1B.hash
new file mode 100644
index 0000000..b13a9ca
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/generate/1B.hash
@@ -0,0 +1 @@
+sha256:fb7841e1b3b3e3511196b38df96e73ac7785edef663ea450f97b3c1322742d69
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/head/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/head/0A.dhall
new file mode 100644
index 0000000..fad0013
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/head/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/head Natural [ 0, 1, 2 ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/head/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/head/0B.hash
new file mode 100644
index 0000000..7e72b9a
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/head/0B.hash
@@ -0,0 +1 @@
+sha256:7ac81b06d39113c93f17cc3d2aa55867453f68f35f58a4d577f5bacbb969225f
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/head/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/head/1A.dhall
new file mode 100644
index 0000000..bd5c640
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/head/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/head Natural ([] : List Natural)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/head/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/head/1B.hash
new file mode 100644
index 0000000..cb5838b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/head/1B.hash
@@ -0,0 +1 @@
+sha256:bfdc295856e05e3610d202d9c12f56f7c423de81cd6069f590786ca176b94df3
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/indexed/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/indexed/0A.dhall
new file mode 100644
index 0000000..0408e5a
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/indexed/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/indexed Bool [ True, False, True ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/indexed/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/indexed/0B.hash
new file mode 100644
index 0000000..c352f2c
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/indexed/0B.hash
@@ -0,0 +1 @@
+sha256:7225a557384940f3f2f7f40e5e3e36384be7892c08a24e5467d0f75cd0dda9e1
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/indexed/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/indexed/1A.dhall
new file mode 100644
index 0000000..ceec7ae
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/indexed/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/indexed Bool ([] : List Bool)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/indexed/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/indexed/1B.hash
new file mode 100644
index 0000000..4c60685
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/indexed/1B.hash
@@ -0,0 +1 @@
+sha256:ff10538dd6bf3bf736bf38f54575e1ddd251aa1d6aad7c6ff6f4159bfc87cc4a
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/iterate/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/iterate/0A.dhall
new file mode 100644
index 0000000..99c68a5
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/iterate/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/iterate 10 Natural (λ(x : Natural) → x * 2) 1
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/iterate/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/iterate/0B.hash
new file mode 100644
index 0000000..cbb9ebc
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/iterate/0B.hash
@@ -0,0 +1 @@
+sha256:577ea4905798b4fbd4803b3a7c82902594f0c3e5d84af46cec4514da9801760a
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/iterate/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/iterate/1A.dhall
new file mode 100644
index 0000000..1859133
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/iterate/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/iterate 0 Natural (λ(x : Natural) → x * 2) 1
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/iterate/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/iterate/1B.hash
new file mode 100644
index 0000000..326cc5d
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/iterate/1B.hash
@@ -0,0 +1 @@
+sha256:d79a2e0e14809ab2dbd2d180e60da8e129a5fb197bdd0caed57e3828402e48a9
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/last/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/last/0A.dhall
new file mode 100644
index 0000000..5ae5653
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/last/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/last Natural [ 0, 1, 2 ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/last/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/last/0B.hash
new file mode 100644
index 0000000..5a1bf4f
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/last/0B.hash
@@ -0,0 +1 @@
+sha256:1400a0fa058e1c8fc58926856000d82d99fad204bf48e36f54dccaafc0acd3a0
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/last/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/last/1A.dhall
new file mode 100644
index 0000000..3556c19
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/last/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/last Natural ([] : List Natural)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/last/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/last/1B.hash
new file mode 100644
index 0000000..cb5838b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/last/1B.hash
@@ -0,0 +1 @@
+sha256:bfdc295856e05e3610d202d9c12f56f7c423de81cd6069f590786ca176b94df3
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/length/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/length/0A.dhall
new file mode 100644
index 0000000..526abba
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/length/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/length Natural [ 0, 1, 2 ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/length/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/length/0B.hash
new file mode 100644
index 0000000..ba88e0f
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/length/0B.hash
@@ -0,0 +1 @@
+sha256:15f52ecf91c94c1baac02d5a4964b2ed8fa401641a2c8a95e8306ec7c1e3b8d2
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/length/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/length/1A.dhall
new file mode 100644
index 0000000..16c23a7
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/length/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/length Natural ([] : List Natural)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/length/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/length/1B.hash
new file mode 100644
index 0000000..b175d49
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/length/1B.hash
@@ -0,0 +1 @@
+sha256:d0a48d41dcc572839faa9499b6c316b8d0d7115efac2ac770f062cd5fd6d0181
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/map/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/map/0A.dhall
new file mode 100644
index 0000000..c087fb4
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/map/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/map Natural Bool Natural/even [ 2, 3, 5 ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/map/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/map/0B.hash
new file mode 100644
index 0000000..01bd1d5
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/map/0B.hash
@@ -0,0 +1 @@
+sha256:aaf20d96e69473f836397764ec61b64a65dc5084ee33692ecd8b85ca63962827
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/map/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/map/1A.dhall
new file mode 100644
index 0000000..903c47a
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/map/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/map Natural Bool Natural/even ([] : List Natural)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/map/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/map/1B.hash
new file mode 100644
index 0000000..b13a9ca
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/map/1B.hash
@@ -0,0 +1 @@
+sha256:fb7841e1b3b3e3511196b38df96e73ac7785edef663ea450f97b3c1322742d69
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/null/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/null/0A.dhall
new file mode 100644
index 0000000..2bd9d99
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/null/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/null Natural [ 0, 1, 2 ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/null/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/null/0B.hash
new file mode 100644
index 0000000..e88d95b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/null/0B.hash
@@ -0,0 +1 @@
+sha256:2017ff3461395672aa0aa4f64894fd2f95a4b120e2690e8951656d79adc2eed2
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/null/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/null/1A.dhall
new file mode 100644
index 0000000..4388e89
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/null/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/null Natural ([] : List Natural)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/null/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/null/1B.hash
new file mode 100644
index 0000000..738b376
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/null/1B.hash
@@ -0,0 +1 @@
+sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/replicate/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/replicate/0A.dhall
new file mode 100644
index 0000000..0175a46
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/replicate/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/replicate 9 Natural 1
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/replicate/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/replicate/0B.hash
new file mode 100644
index 0000000..1217b56
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/replicate/0B.hash
@@ -0,0 +1 @@
+sha256:4241079fe7c8a46be37831a35dedb60645c3a86a2ab24778e03c27c820813cdc
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/replicate/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/replicate/1A.dhall
new file mode 100644
index 0000000..3e2d5b5
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/replicate/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/replicate 0 Natural 1
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/replicate/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/replicate/1B.hash
new file mode 100644
index 0000000..326cc5d
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/replicate/1B.hash
@@ -0,0 +1 @@
+sha256:d79a2e0e14809ab2dbd2d180e60da8e129a5fb197bdd0caed57e3828402e48a9
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/reverse/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/reverse/0A.dhall
new file mode 100644
index 0000000..d1c7335
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/reverse/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/reverse Natural [ 0, 1, 2 ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/reverse/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/reverse/0B.hash
new file mode 100644
index 0000000..9f0fe5a
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/reverse/0B.hash
@@ -0,0 +1 @@
+sha256:ed586af4895ad8118e77976c6ee2fef5a39f69eb9378df32349c81fee2d61d4d
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/reverse/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/reverse/1A.dhall
new file mode 100644
index 0000000..6a6d5f6
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/reverse/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/reverse Natural ([] : List Natural)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/reverse/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/reverse/1B.hash
new file mode 100644
index 0000000..326cc5d
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/reverse/1B.hash
@@ -0,0 +1 @@
+sha256:d79a2e0e14809ab2dbd2d180e60da8e129a5fb197bdd0caed57e3828402e48a9
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/shifted/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/shifted/0A.dhall
new file mode 100644
index 0000000..f8f4be0
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/shifted/0A.dhall
@@ -0,0 +1,15 @@
+../../../../../../Prelude/List/shifted
+Bool
+[ [ { index = 0, value = True }
+ , { index = 1, value = True }
+ , { index = 2, value = False }
+ ]
+, [ { index = 0, value = False }
+ , { index = 1, value = False }
+ ]
+, [ { index = 0, value = True }
+ , { index = 1, value = True }
+ , { index = 2, value = True }
+ , { index = 3, value = True }
+ ]
+]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/shifted/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/shifted/0B.hash
new file mode 100644
index 0000000..9a1f303
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/shifted/0B.hash
@@ -0,0 +1 @@
+sha256:e5c27411e9b0692ac96e6914420f17748eda33d3854067675c6a3b3780fb15a6
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/shifted/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/shifted/1A.dhall
new file mode 100644
index 0000000..1744358
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/shifted/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/shifted Bool ([] : List (List { index : Natural, value : Bool }))
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/shifted/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/shifted/1B.hash
new file mode 100644
index 0000000..4c60685
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/shifted/1B.hash
@@ -0,0 +1 @@
+sha256:ff10538dd6bf3bf736bf38f54575e1ddd251aa1d6aad7c6ff6f4159bfc87cc4a
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/unzip/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/unzip/0A.dhall
new file mode 100644
index 0000000..6265af3
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/unzip/0A.dhall
@@ -0,0 +1,7 @@
+../../../../../../Prelude/List/unzip
+Text
+Bool
+[ { _1 = "ABC", _2 = True }
+, { _1 = "DEF", _2 = False }
+, { _1 = "GHI", _2 = True }
+]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/unzip/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/unzip/0B.hash
new file mode 100644
index 0000000..25c5350
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/unzip/0B.hash
@@ -0,0 +1 @@
+sha256:fffb0db166d08b99a1beb1650a3c9ee6e7bf6ce1054150bea4dae9b8ce5e4fbf
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/unzip/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/List/unzip/1A.dhall
new file mode 100644
index 0000000..7434a25
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/unzip/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/List/unzip Text Bool ([] : List { _1 : Text, _2 : Bool })
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/List/unzip/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/List/unzip/1B.hash
new file mode 100644
index 0000000..a1b690b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/List/unzip/1B.hash
@@ -0,0 +1 @@
+sha256:c598ac5f10c7d20fe201f94ed5d9d18a847e89c65db9478492c930e5c42af710
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/build/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Natural/build/0A.dhall
new file mode 100644
index 0000000..18586cb
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/build/0A.dhall
@@ -0,0 +1,6 @@
+../../../../../../Prelude/Natural/build
+( λ(natural : Type)
+→ λ(succ : natural → natural)
+→ λ(zero : natural)
+→ succ (succ (succ zero))
+)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/build/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Natural/build/0B.hash
new file mode 100644
index 0000000..ba88e0f
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/build/0B.hash
@@ -0,0 +1 @@
+sha256:15f52ecf91c94c1baac02d5a4964b2ed8fa401641a2c8a95e8306ec7c1e3b8d2
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/build/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Natural/build/1A.dhall
new file mode 100644
index 0000000..d047250
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/build/1A.dhall
@@ -0,0 +1,6 @@
+../../../../../../Prelude/Natural/build
+( λ(natural : Type)
+→ λ(succ : natural → natural)
+→ λ(zero : natural)
+→ zero
+)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/build/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Natural/build/1B.hash
new file mode 100644
index 0000000..b175d49
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/build/1B.hash
@@ -0,0 +1 @@
+sha256:d0a48d41dcc572839faa9499b6c316b8d0d7115efac2ac770f062cd5fd6d0181
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/enumerate/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Natural/enumerate/0A.dhall
new file mode 100644
index 0000000..b631e71
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/enumerate/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Natural/enumerate 10
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/enumerate/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Natural/enumerate/0B.hash
new file mode 100644
index 0000000..e0c3d74
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/enumerate/0B.hash
@@ -0,0 +1 @@
+sha256:a7af1902b53cc68a9613b659ebf58d06c840072625d14f9fde7eefa0e0f2add0
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/enumerate/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Natural/enumerate/1A.dhall
new file mode 100644
index 0000000..6d46af4
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/enumerate/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Natural/enumerate 0
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/enumerate/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Natural/enumerate/1B.hash
new file mode 100644
index 0000000..326cc5d
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/enumerate/1B.hash
@@ -0,0 +1 @@
+sha256:d79a2e0e14809ab2dbd2d180e60da8e129a5fb197bdd0caed57e3828402e48a9
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/even/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Natural/even/0A.dhall
new file mode 100644
index 0000000..51cda91
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/even/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Natural/even 3
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/even/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Natural/even/0B.hash
new file mode 100644
index 0000000..e88d95b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/even/0B.hash
@@ -0,0 +1 @@
+sha256:2017ff3461395672aa0aa4f64894fd2f95a4b120e2690e8951656d79adc2eed2
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/even/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Natural/even/1A.dhall
new file mode 100644
index 0000000..03a3629
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/even/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Natural/even 0
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/even/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Natural/even/1B.hash
new file mode 100644
index 0000000..738b376
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/even/1B.hash
@@ -0,0 +1 @@
+sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/0A.dhall
new file mode 100644
index 0000000..3275ec1
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Natural/fold 3 Natural (λ(x : Natural) → 5 * x) 1
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/0B.hash
new file mode 100644
index 0000000..da5f3fa
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/0B.hash
@@ -0,0 +1 @@
+sha256:39b0b6e0e0b616af4f20c7b06fefcd26dcdbd5be772d885fe73487574ec8b56b
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/1A.dhall
new file mode 100644
index 0000000..9cbb617
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/1A.dhall
@@ -0,0 +1 @@
+λ(zero : Natural) → ../../../../../../Prelude/Natural/fold 3 Natural (λ(x : Natural) → 5 * x) zero
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/1B.hash
new file mode 100644
index 0000000..f39c232
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/1B.hash
@@ -0,0 +1 @@
+sha256:c6ddb630f2abfcd78aa874079323ba2a9f80f548c5687346a0fcedff78d14f52
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/2A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/2A.dhall
new file mode 100644
index 0000000..05b6925
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/2A.dhall
@@ -0,0 +1,4 @@
+ λ(natural : Type)
+→ λ(succ : natural → natural)
+→ λ(zero : natural)
+→ ../../../../../../Prelude/Natural/fold 3 natural succ zero
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/2B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/2B.hash
new file mode 100644
index 0000000..3c30e01
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/2B.hash
@@ -0,0 +1 @@
+sha256:08681d6fb9b1bb78be37f5a976186daa8fc39d0d1d3f7dbb716dc33937a6746d
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/isZero/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Natural/isZero/0A.dhall
new file mode 100644
index 0000000..0d85f80
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/isZero/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Natural/isZero 2
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/isZero/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Natural/isZero/0B.hash
new file mode 100644
index 0000000..e88d95b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/isZero/0B.hash
@@ -0,0 +1 @@
+sha256:2017ff3461395672aa0aa4f64894fd2f95a4b120e2690e8951656d79adc2eed2
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/isZero/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Natural/isZero/1A.dhall
new file mode 100644
index 0000000..22c9226
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/isZero/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Natural/isZero 0
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/isZero/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Natural/isZero/1B.hash
new file mode 100644
index 0000000..738b376
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/isZero/1B.hash
@@ -0,0 +1 @@
+sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/odd/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Natural/odd/0A.dhall
new file mode 100644
index 0000000..00b0061
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/odd/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Natural/odd 3
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/odd/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Natural/odd/0B.hash
new file mode 100644
index 0000000..738b376
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/odd/0B.hash
@@ -0,0 +1 @@
+sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/odd/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Natural/odd/1A.dhall
new file mode 100644
index 0000000..64efb46
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/odd/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Natural/odd 0
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/odd/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Natural/odd/1B.hash
new file mode 100644
index 0000000..e88d95b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/odd/1B.hash
@@ -0,0 +1 @@
+sha256:2017ff3461395672aa0aa4f64894fd2f95a4b120e2690e8951656d79adc2eed2
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/product/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Natural/product/0A.dhall
new file mode 100644
index 0000000..4a8990f
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/product/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Natural/product [ 2, 3, 5 ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/product/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Natural/product/0B.hash
new file mode 100644
index 0000000..81b9d68
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/product/0B.hash
@@ -0,0 +1 @@
+sha256:49036d5d861d35d4aff797975a3447ebae71a9057951a03fc810ab8e8e00a498
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/product/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Natural/product/1A.dhall
new file mode 100644
index 0000000..ab232ca
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/product/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Natural/product ([] : List Natural)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/product/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Natural/product/1B.hash
new file mode 100644
index 0000000..ae27037
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/product/1B.hash
@@ -0,0 +1 @@
+sha256:d60d8415e36e86dae7f42933d3b0c4fe3ca238f057fba206c7e9fbf5d784fe15
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/show/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Natural/show/0A.dhall
new file mode 100644
index 0000000..1849aac
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/show/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Natural/show 3
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/show/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Natural/show/0B.hash
new file mode 100644
index 0000000..6bbfd81
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/show/0B.hash
@@ -0,0 +1 @@
+sha256:c8911e8084484ca0d468334986a19f0a11cc18b31f41f272e7d4ad2cd479ad39
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/show/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Natural/show/1A.dhall
new file mode 100644
index 0000000..a6294ce
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/show/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Natural/show 0
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/show/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Natural/show/1B.hash
new file mode 100644
index 0000000..1af3a93
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/show/1B.hash
@@ -0,0 +1 @@
+sha256:e3062e0493964ebaef8880667ad8a6289c277618c0b31141610abf5d69e7c9ea
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/sum/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Natural/sum/0A.dhall
new file mode 100644
index 0000000..586097e
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/sum/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Natural/sum [ 2, 3, 5 ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/sum/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Natural/sum/0B.hash
new file mode 100644
index 0000000..ed551fb
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/sum/0B.hash
@@ -0,0 +1 @@
+sha256:d4428061b6fd69b6b45574603ac71060f9756a5c9a1642df322812e3a7ea858b
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/sum/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Natural/sum/1A.dhall
new file mode 100644
index 0000000..e83b1f0
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/sum/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Natural/sum ([] : List Natural)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/sum/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Natural/sum/1B.hash
new file mode 100644
index 0000000..b175d49
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/sum/1B.hash
@@ -0,0 +1 @@
+sha256:d0a48d41dcc572839faa9499b6c316b8d0d7115efac2ac770f062cd5fd6d0181
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/toDouble/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Natural/toDouble/0A.dhall
new file mode 100644
index 0000000..85c3024
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/toDouble/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Natural/toDouble 3
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/toDouble/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Natural/toDouble/0B.hash
new file mode 100644
index 0000000..f66ab42
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/toDouble/0B.hash
@@ -0,0 +1 @@
+sha256:e894ad5c9620a9932e7025f1148823d20abada43ec7f6e50cbd89751a7ba638f
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/toDouble/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Natural/toDouble/1A.dhall
new file mode 100644
index 0000000..75411d9
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/toDouble/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Natural/toDouble 0
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/toDouble/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Natural/toDouble/1B.hash
new file mode 100644
index 0000000..102f7d7
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/toDouble/1B.hash
@@ -0,0 +1 @@
+sha256:3c213998cb56b97b31168d9dce02d084fb5f5103caef41fb6dc375f593749a7d
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/toInteger/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Natural/toInteger/0A.dhall
new file mode 100644
index 0000000..2a0fb62
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/toInteger/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Natural/toInteger 3
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/toInteger/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Natural/toInteger/0B.hash
new file mode 100644
index 0000000..838c044
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/toInteger/0B.hash
@@ -0,0 +1 @@
+sha256:aa773179ef61a5d65c774bcc510806531ce8fa97c550961526153e42959e6f76
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/toInteger/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Natural/toInteger/1A.dhall
new file mode 100644
index 0000000..9a64296
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/toInteger/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Natural/toInteger 0
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Natural/toInteger/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Natural/toInteger/1B.hash
new file mode 100644
index 0000000..711729d
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Natural/toInteger/1B.hash
@@ -0,0 +1 @@
+sha256:5abe149a174ca99b6da92c97b0a7c8900a5f9acddb720bf7173eef877c6a187b
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/all/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/all/0A.dhall
new file mode 100644
index 0000000..b6b8cfe
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/all/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Optional/all Natural Natural/even (Some 3)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/all/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/all/0B.hash
new file mode 100644
index 0000000..e88d95b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/all/0B.hash
@@ -0,0 +1 @@
+sha256:2017ff3461395672aa0aa4f64894fd2f95a4b120e2690e8951656d79adc2eed2
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/all/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/all/1A.dhall
new file mode 100644
index 0000000..c9cb22d
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/all/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Optional/all Natural Natural/even (None Natural)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/all/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/all/1B.hash
new file mode 100644
index 0000000..738b376
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/all/1B.hash
@@ -0,0 +1 @@
+sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/any/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/any/0A.dhall
new file mode 100644
index 0000000..6719885
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/any/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Optional/any Natural Natural/even (Some 2)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/any/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/any/0B.hash
new file mode 100644
index 0000000..738b376
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/any/0B.hash
@@ -0,0 +1 @@
+sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/any/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/any/1A.dhall
new file mode 100644
index 0000000..548fdb5
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/any/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Optional/any Natural Natural/even (None Natural)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/any/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/any/1B.hash
new file mode 100644
index 0000000..e88d95b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/any/1B.hash
@@ -0,0 +1 @@
+sha256:2017ff3461395672aa0aa4f64894fd2f95a4b120e2690e8951656d79adc2eed2
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/build/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/build/0A.dhall
new file mode 100644
index 0000000..3c98847
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/build/0A.dhall
@@ -0,0 +1,7 @@
+../../../../../../Prelude/Optional/build
+Natural
+( λ(optional : Type)
+→ λ(some : Natural → optional)
+→ λ(none : optional)
+→ some 1
+)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/build/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/build/0B.hash
new file mode 100644
index 0000000..ab0f021
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/build/0B.hash
@@ -0,0 +1 @@
+sha256:033652a641ac54a27f52b874877889c6a9c7f8c435dae9f8e956e4d402d6f2c7
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/build/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/build/1A.dhall
new file mode 100644
index 0000000..c8be913
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/build/1A.dhall
@@ -0,0 +1,7 @@
+../../../../../../Prelude/Optional/build
+Natural
+( λ(optional : Type)
+→ λ(some : Natural → optional)
+→ λ(none : optional)
+→ none
+)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/build/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/build/1B.hash
new file mode 100644
index 0000000..cb5838b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/build/1B.hash
@@ -0,0 +1 @@
+sha256:bfdc295856e05e3610d202d9c12f56f7c423de81cd6069f590786ca176b94df3
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/0A.dhall
new file mode 100644
index 0000000..3bd6d84
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Optional/concat Natural (Some (Some 1))
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/0B.hash
new file mode 100644
index 0000000..ab0f021
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/0B.hash
@@ -0,0 +1 @@
+sha256:033652a641ac54a27f52b874877889c6a9c7f8c435dae9f8e956e4d402d6f2c7
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/1A.dhall
new file mode 100644
index 0000000..c82ee2f
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Optional/concat Natural (Some (None Natural))
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/1B.hash
new file mode 100644
index 0000000..cb5838b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/1B.hash
@@ -0,0 +1 @@
+sha256:bfdc295856e05e3610d202d9c12f56f7c423de81cd6069f590786ca176b94df3
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/2A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/2A.dhall
new file mode 100644
index 0000000..133a4ab
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/2A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Optional/concat Natural (None (Optional Natural))
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/2B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/2B.hash
new file mode 100644
index 0000000..cb5838b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/2B.hash
@@ -0,0 +1 @@
+sha256:bfdc295856e05e3610d202d9c12f56f7c423de81cd6069f590786ca176b94df3
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/filter/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/filter/0A.dhall
new file mode 100644
index 0000000..7f53205
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/filter/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Optional/filter Natural Natural/even (Some 2)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/filter/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/filter/0B.hash
new file mode 100644
index 0000000..5a1bf4f
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/filter/0B.hash
@@ -0,0 +1 @@
+sha256:1400a0fa058e1c8fc58926856000d82d99fad204bf48e36f54dccaafc0acd3a0
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/filter/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/filter/1A.dhall
new file mode 100644
index 0000000..d65a37b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/filter/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Optional/filter Natural Natural/odd (Some 2)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/filter/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/filter/1B.hash
new file mode 100644
index 0000000..cb5838b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/filter/1B.hash
@@ -0,0 +1 @@
+sha256:bfdc295856e05e3610d202d9c12f56f7c423de81cd6069f590786ca176b94df3
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/fold/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/fold/0A.dhall
new file mode 100644
index 0000000..eee9edc
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/fold/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Optional/fold Natural (Some 2) Natural (λ(x : Natural) → x) 0
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/fold/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/fold/0B.hash
new file mode 100644
index 0000000..e8635e8
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/fold/0B.hash
@@ -0,0 +1 @@
+sha256:4caf97e8c445d4d4b5c5b992973e098ed4ae88a355915f5a59db640a589bc9cb
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/fold/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/fold/1A.dhall
new file mode 100644
index 0000000..38dc80b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/fold/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Optional/fold Natural (None Natural) Natural (λ(x : Natural) → x) 0
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/fold/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/fold/1B.hash
new file mode 100644
index 0000000..b175d49
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/fold/1B.hash
@@ -0,0 +1 @@
+sha256:d0a48d41dcc572839faa9499b6c316b8d0d7115efac2ac770f062cd5fd6d0181
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/head/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/head/0A.dhall
new file mode 100644
index 0000000..ad677a9
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/head/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Optional/head Natural [ None Natural, Some 1, Some 2 ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/head/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/head/0B.hash
new file mode 100644
index 0000000..ab0f021
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/head/0B.hash
@@ -0,0 +1 @@
+sha256:033652a641ac54a27f52b874877889c6a9c7f8c435dae9f8e956e4d402d6f2c7
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/head/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/head/1A.dhall
new file mode 100644
index 0000000..18c321a
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/head/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Optional/head Natural [ None Natural, None Natural ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/head/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/head/1B.hash
new file mode 100644
index 0000000..cb5838b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/head/1B.hash
@@ -0,0 +1 @@
+sha256:bfdc295856e05e3610d202d9c12f56f7c423de81cd6069f590786ca176b94df3
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/head/2A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/head/2A.dhall
new file mode 100644
index 0000000..f12f023
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/head/2A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Optional/head Natural ([] : List (Optional Natural))
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/head/2B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/head/2B.hash
new file mode 100644
index 0000000..cb5838b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/head/2B.hash
@@ -0,0 +1 @@
+sha256:bfdc295856e05e3610d202d9c12f56f7c423de81cd6069f590786ca176b94df3
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/last/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/last/0A.dhall
new file mode 100644
index 0000000..3be9680
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/last/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Optional/last Natural [ None Natural, Some 1, Some 2 ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/last/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/last/0B.hash
new file mode 100644
index 0000000..5a1bf4f
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/last/0B.hash
@@ -0,0 +1 @@
+sha256:1400a0fa058e1c8fc58926856000d82d99fad204bf48e36f54dccaafc0acd3a0
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/last/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/last/1A.dhall
new file mode 100644
index 0000000..1a049aa
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/last/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Optional/last Natural [ None Natural, None Natural ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/last/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/last/1B.hash
new file mode 100644
index 0000000..cb5838b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/last/1B.hash
@@ -0,0 +1 @@
+sha256:bfdc295856e05e3610d202d9c12f56f7c423de81cd6069f590786ca176b94df3
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/last/2A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/last/2A.dhall
new file mode 100644
index 0000000..f723a10
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/last/2A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Optional/last Natural ([] : List (Optional Natural))
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/last/2B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/last/2B.hash
new file mode 100644
index 0000000..cb5838b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/last/2B.hash
@@ -0,0 +1 @@
+sha256:bfdc295856e05e3610d202d9c12f56f7c423de81cd6069f590786ca176b94df3
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/length/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/length/0A.dhall
new file mode 100644
index 0000000..331fd37
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/length/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Optional/length Natural (Some 2)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/length/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/length/0B.hash
new file mode 100644
index 0000000..ae27037
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/length/0B.hash
@@ -0,0 +1 @@
+sha256:d60d8415e36e86dae7f42933d3b0c4fe3ca238f057fba206c7e9fbf5d784fe15
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/length/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/length/1A.dhall
new file mode 100644
index 0000000..d86759e
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/length/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Optional/length Natural (None Natural)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/length/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/length/1B.hash
new file mode 100644
index 0000000..b175d49
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/length/1B.hash
@@ -0,0 +1 @@
+sha256:d0a48d41dcc572839faa9499b6c316b8d0d7115efac2ac770f062cd5fd6d0181
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/map/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/map/0A.dhall
new file mode 100644
index 0000000..b8424bc
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/map/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Optional/map Natural Bool Natural/even (Some 3)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/map/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/map/0B.hash
new file mode 100644
index 0000000..dbd024a
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/map/0B.hash
@@ -0,0 +1 @@
+sha256:3af5b2f9dcc58e7950e2f0281f796de2ac5e87554ae758e38c36cd55cf53743e
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/map/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/map/1A.dhall
new file mode 100644
index 0000000..8424618
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/map/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Optional/map Natural Bool Natural/even (None Natural)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/map/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/map/1B.hash
new file mode 100644
index 0000000..5773301
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/map/1B.hash
@@ -0,0 +1 @@
+sha256:2c9884f8336ed425b13068919b216c42be286636c657faa15b911382436b3f00
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/null/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/null/0A.dhall
new file mode 100644
index 0000000..a9e1e85
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/null/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Optional/null Natural (Some 2)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/null/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/null/0B.hash
new file mode 100644
index 0000000..e88d95b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/null/0B.hash
@@ -0,0 +1 @@
+sha256:2017ff3461395672aa0aa4f64894fd2f95a4b120e2690e8951656d79adc2eed2
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/null/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/null/1A.dhall
new file mode 100644
index 0000000..9f006bc
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/null/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Optional/null Natural (None Natural)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/null/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/null/1B.hash
new file mode 100644
index 0000000..738b376
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/null/1B.hash
@@ -0,0 +1 @@
+sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/toList/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/toList/0A.dhall
new file mode 100644
index 0000000..79ec635
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/toList/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Optional/toList Natural (Some 1)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/toList/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/toList/0B.hash
new file mode 100644
index 0000000..a1dda70
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/toList/0B.hash
@@ -0,0 +1 @@
+sha256:75be41333b1ef7a6f5c5cfbcd6097681f3968736dc393b9bf53b2e609564217f
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/toList/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/toList/1A.dhall
new file mode 100644
index 0000000..076f10d
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/toList/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Optional/toList Natural (None Natural)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/toList/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/toList/1B.hash
new file mode 100644
index 0000000..326cc5d
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/toList/1B.hash
@@ -0,0 +1 @@
+sha256:d79a2e0e14809ab2dbd2d180e60da8e129a5fb197bdd0caed57e3828402e48a9
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/unzip/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/unzip/0A.dhall
new file mode 100644
index 0000000..71a52f8
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/unzip/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Optional/unzip Text Bool (Some { _1 = "ABC", _2 = True })
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/unzip/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/unzip/0B.hash
new file mode 100644
index 0000000..e03637b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/unzip/0B.hash
@@ -0,0 +1 @@
+sha256:5604f6ef6cf7385166101c61738c34a84983f1b7b4695858fa2068fc669eb2c1
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/unzip/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Optional/unzip/1A.dhall
new file mode 100644
index 0000000..2757461
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/unzip/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Optional/unzip Text Bool (None { _1 : Text, _2 : Bool })
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Optional/unzip/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Optional/unzip/1B.hash
new file mode 100644
index 0000000..90d048f
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Optional/unzip/1B.hash
@@ -0,0 +1 @@
+sha256:6de82c54048538c97063c9ae31919b4ca21018ae7119bc123508c136ee653280
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Text/concat/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Text/concat/0A.dhall
new file mode 100644
index 0000000..51a2545
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Text/concat/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Text/concat [ "ABC", "DEF", "GHI" ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Text/concat/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Text/concat/0B.hash
new file mode 100644
index 0000000..ef166a0
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Text/concat/0B.hash
@@ -0,0 +1 @@
+sha256:1f73cf8a6efa724376c3342f9e0104c499e16420732b8c25efc6ab1c18979772
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Text/concat/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Text/concat/1A.dhall
new file mode 100644
index 0000000..b28735c
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Text/concat/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Text/concat ([] : List Text)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Text/concat/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Text/concat/1B.hash
new file mode 100644
index 0000000..89a9ab6
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Text/concat/1B.hash
@@ -0,0 +1 @@
+sha256:f08ed5225480d827ff3ce74b756afa6330f66d974d6f0d6160d767b5c45642aa
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Text/concatMap/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Text/concatMap/0A.dhall
new file mode 100644
index 0000000..f13cf9e
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Text/concatMap/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Text/concatMap Natural (λ(n : Natural) → "${Natural/show n} ") [ 0, 1, 2 ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Text/concatMap/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Text/concatMap/0B.hash
new file mode 100644
index 0000000..a1f1539
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Text/concatMap/0B.hash
@@ -0,0 +1 @@
+sha256:fa7f18d0522f120dbf229ff0a55f96792ce76613ba17611c53f3f5efd81df510
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Text/concatMap/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Text/concatMap/1A.dhall
new file mode 100644
index 0000000..45f1ab3
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Text/concatMap/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Text/concatMap Natural (λ(n : Natural) → "${Natural/show n} ") ([] : List Natural)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Text/concatMap/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Text/concatMap/1B.hash
new file mode 100644
index 0000000..89a9ab6
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Text/concatMap/1B.hash
@@ -0,0 +1 @@
+sha256:f08ed5225480d827ff3ce74b756afa6330f66d974d6f0d6160d767b5c45642aa
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Text/concatMapSep/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Text/concatMapSep/0A.dhall
new file mode 100644
index 0000000..6fa70ec
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Text/concatMapSep/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Text/concatMapSep ", " Natural Natural/show [ 0, 1, 2 ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Text/concatMapSep/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Text/concatMapSep/0B.hash
new file mode 100644
index 0000000..cfacb7f
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Text/concatMapSep/0B.hash
@@ -0,0 +1 @@
+sha256:952e63727a69b5f2db65645167c3a8f60dbc350608562a1c90423c819a1b5baf
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Text/concatMapSep/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Text/concatMapSep/1A.dhall
new file mode 100644
index 0000000..3bc9548
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Text/concatMapSep/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Text/concatMapSep ", " Natural Natural/show ([] : List Natural)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Text/concatMapSep/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Text/concatMapSep/1B.hash
new file mode 100644
index 0000000..89a9ab6
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Text/concatMapSep/1B.hash
@@ -0,0 +1 @@
+sha256:f08ed5225480d827ff3ce74b756afa6330f66d974d6f0d6160d767b5c45642aa
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Text/concatSep/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Text/concatSep/0A.dhall
new file mode 100644
index 0000000..9c3cdd1
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Text/concatSep/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Text/concatSep ", " [ "ABC", "DEF", "GHI" ]
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Text/concatSep/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Text/concatSep/0B.hash
new file mode 100644
index 0000000..43d7357
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Text/concatSep/0B.hash
@@ -0,0 +1 @@
+sha256:151ad6d86cced932c9ed6fa5d69b88fb47e160a13762f4d92dcb1e847ccd30d6
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Text/concatSep/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Text/concatSep/1A.dhall
new file mode 100644
index 0000000..be99b31
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Text/concatSep/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Text/concatSep ", " ([] : List Text)
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Text/concatSep/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Text/concatSep/1B.hash
new file mode 100644
index 0000000..89a9ab6
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Text/concatSep/1B.hash
@@ -0,0 +1 @@
+sha256:f08ed5225480d827ff3ce74b756afa6330f66d974d6f0d6160d767b5c45642aa
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Text/show/0A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Text/show/0A.dhall
new file mode 100644
index 0000000..6f5ce98
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Text/show/0A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Text/show "ABC"
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Text/show/0B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Text/show/0B.hash
new file mode 100644
index 0000000..fc76baf
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Text/show/0B.hash
@@ -0,0 +1 @@
+sha256:8dffa347e98424c7b1e91e3e3758fc203a4e52fd990dc4b050da18cdb39655d3
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Text/show/1A.dhall b/dhall-lang/tests/semantic-hash/success/prelude/Text/show/1A.dhall
new file mode 100644
index 0000000..aa7da13
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Text/show/1A.dhall
@@ -0,0 +1 @@
+../../../../../../Prelude/Text/show "\u0000 \$ \\ \n \u263a"
diff --git a/dhall-lang/tests/semantic-hash/success/prelude/Text/show/1B.hash b/dhall-lang/tests/semantic-hash/success/prelude/Text/show/1B.hash
new file mode 100644
index 0000000..27a5595
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/prelude/Text/show/1B.hash
@@ -0,0 +1 @@
+sha256:92655b5ee59ddfb1decfd19cf8b37e8f2dd5dbd317f55bcbb780bf6ed2010b0a
diff --git a/dhall-lang/tests/semantic-hash/success/remoteSystemsA.dhall b/dhall-lang/tests/semantic-hash/success/remoteSystemsA.dhall
new file mode 100644
index 0000000..0c07296
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/remoteSystemsA.dhall
@@ -0,0 +1,52 @@
+let Text/concatMap = ../../../Prelude/Text/concatMap
+
+let Text/concatSep = ../../../Prelude/Text/concatSep
+
+let Row =
+ { cores :
+ Natural
+ , host :
+ Text
+ , key :
+ Text
+ , mandatoryFeatures :
+ List Text
+ , platforms :
+ List Text
+ , speedFactor :
+ Natural
+ , supportedFeatures :
+ List Text
+ , user :
+ Optional Text
+ }
+
+let renderRow =
+ λ ( row
+ : Row
+ )
+ → let host =
+ Optional/fold
+ Text
+ row.user
+ Text
+ (λ(user : Text) → "${user}@${row.host}")
+ row.host
+
+ let platforms = Text/concatSep "," row.platforms
+
+ let key = row.key
+
+ let cores = Integer/show (Natural/toInteger row.cores)
+
+ let speedFactor = Integer/show (Natural/toInteger row.speedFactor)
+
+ let supportedFeatures = Text/concatSep "," row.supportedFeatures
+
+ let mandatoryFeatures = Text/concatSep "," row.mandatoryFeatures
+
+ in ''
+ ${host} ${platforms} ${key} ${cores} ${speedFactor} ${supportedFeatures} ${mandatoryFeatures}
+ ''
+
+in Text/concatMap Row renderRow
diff --git a/dhall-lang/tests/semantic-hash/success/remoteSystemsB.hash b/dhall-lang/tests/semantic-hash/success/remoteSystemsB.hash
new file mode 100644
index 0000000..81690d8
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/remoteSystemsB.hash
@@ -0,0 +1 @@
+sha256:1591a538ac60355f6f988d01edb3b8622d2631b93177a90ad7172e0f88b67da5
diff --git a/dhall-lang/tests/semantic-hash/success/simple/doubleShowA.dhall b/dhall-lang/tests/semantic-hash/success/simple/doubleShowA.dhall
new file mode 100644
index 0000000..54ea2ee
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/doubleShowA.dhall
@@ -0,0 +1,6 @@
+{ example0 = Double/show -0.42
+, example1 = Double/show 13.37
+, example2 = Double/show NaN
+, example3 = Double/show Infinity
+, example4 = Double/show -Infinity
+}
diff --git a/dhall-lang/tests/semantic-hash/success/simple/doubleShowB.hash b/dhall-lang/tests/semantic-hash/success/simple/doubleShowB.hash
new file mode 100644
index 0000000..3897d21
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/doubleShowB.hash
@@ -0,0 +1 @@
+sha256:519ea07f25f759795d4326f06a97401fe0a5efe7823139976d1158c939ee6176
diff --git a/dhall-lang/tests/semantic-hash/success/simple/enumA.dhall b/dhall-lang/tests/semantic-hash/success/simple/enumA.dhall
new file mode 100644
index 0000000..f69391e
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/enumA.dhall
@@ -0,0 +1,8 @@
+let Role = < Wizard | Fighter | Rogue >
+
+let show : Role → Text
+ =
+ λ(x : Role)
+ → merge { Wizard = "Wizard", Fighter = "Fighter", Rogue = "Rogue" } x
+
+in show Role.Wizard
diff --git a/dhall-lang/tests/semantic-hash/success/simple/enumB.hash b/dhall-lang/tests/semantic-hash/success/simple/enumB.hash
new file mode 100644
index 0000000..8824880
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/enumB.hash
@@ -0,0 +1 @@
+sha256:0e6e479638f87eca04805548d70b5de9d22c5359e7d84ccbcfe148577bc25a4e
diff --git a/dhall-lang/tests/semantic-hash/success/simple/integerShowA.dhall b/dhall-lang/tests/semantic-hash/success/simple/integerShowA.dhall
new file mode 100644
index 0000000..2c26dc0
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/integerShowA.dhall
@@ -0,0 +1,4 @@
+{ example0 = Integer/show +1337
+, example1 = Integer/show -42
+, example2 = Integer/show +0
+}
diff --git a/dhall-lang/tests/semantic-hash/success/simple/integerShowB.hash b/dhall-lang/tests/semantic-hash/success/simple/integerShowB.hash
new file mode 100644
index 0000000..4983fab
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/integerShowB.hash
@@ -0,0 +1 @@
+sha256:7ff01ad1c68550be713834548385874f38fd7b989e3c4b8cad7125bc266e2bb3
diff --git a/dhall-lang/tests/semantic-hash/success/simple/integerToDoubleA.dhall b/dhall-lang/tests/semantic-hash/success/simple/integerToDoubleA.dhall
new file mode 100644
index 0000000..5055208
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/integerToDoubleA.dhall
@@ -0,0 +1,10 @@
+[ Integer/toDouble +179769313486231580793728971405303415079934132710037826936173778980444968292764750946649017977587207096330286416692887910946555547851940402630657488671505820681908902000708383676273854845817711531764475730270069855571366959622842914819860834936475292719074168444365510704342711559699508093042880177904174497792
+, Integer/toDouble +179769313486231580793728971405303415079934132710037826936173778980444968292764750946649017977587207096330286416692887910946555547851940402630657488671505820681908902000708383676273854845817711531764475730270069855571366959622842914819860834936475292719074168444365510704342711559699508093042880177904174497791
+, Integer/toDouble +179769313486231560835325876058105298516207002341652166261661174625869553267292326574530099287946549246750631490335877017522087105926987962906277604735569213290190919152394180476217125334960946356387261286640198029037799514183602981511756283727771403830521483963923935633133642802139091669457927874464075218945
+, Integer/toDouble +179769313486231560835325876058105298516207002341652166261661174625869553267292326574530099287946549246750631490335877017522087105926987962906277604735569213290190919152394180476217125334960946356387261286640198029037799514183602981511756283727771403830521483963923935633133642802139091669457927874464075218944
+
+, Integer/toDouble -179769313486231580793728971405303415079934132710037826936173778980444968292764750946649017977587207096330286416692887910946555547851940402630657488671505820681908902000708383676273854845817711531764475730270069855571366959622842914819860834936475292719074168444365510704342711559699508093042880177904174497792
+, Integer/toDouble -179769313486231580793728971405303415079934132710037826936173778980444968292764750946649017977587207096330286416692887910946555547851940402630657488671505820681908902000708383676273854845817711531764475730270069855571366959622842914819860834936475292719074168444365510704342711559699508093042880177904174497791
+, Integer/toDouble -179769313486231560835325876058105298516207002341652166261661174625869553267292326574530099287946549246750631490335877017522087105926987962906277604735569213290190919152394180476217125334960946356387261286640198029037799514183602981511756283727771403830521483963923935633133642802139091669457927874464075218945
+, Integer/toDouble -179769313486231560835325876058105298516207002341652166261661174625869553267292326574530099287946549246750631490335877017522087105926987962906277604735569213290190919152394180476217125334960946356387261286640198029037799514183602981511756283727771403830521483963923935633133642802139091669457927874464075218944
+]
diff --git a/dhall-lang/tests/semantic-hash/success/simple/integerToDoubleB.hash b/dhall-lang/tests/semantic-hash/success/simple/integerToDoubleB.hash
new file mode 100644
index 0000000..3671413
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/integerToDoubleB.hash
@@ -0,0 +1 @@
+sha256:439d81a4aee03a27da069772c4ea51d64c025faac1a2e749734cc5e4cf0f2484
diff --git a/dhall-lang/tests/semantic-hash/success/simple/letletA.dhall b/dhall-lang/tests/semantic-hash/success/simple/letletA.dhall
new file mode 100644
index 0000000..3307452
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/letletA.dhall
@@ -0,0 +1,3 @@
+let l = λ(n : Natural) → λ(m : Natural) → λ(x : Natural) → n + m * x
+let f = l 2 3
+in f 445
diff --git a/dhall-lang/tests/semantic-hash/success/simple/letletB.hash b/dhall-lang/tests/semantic-hash/success/simple/letletB.hash
new file mode 100644
index 0000000..e5fff58
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/letletB.hash
@@ -0,0 +1 @@
+sha256:97285916da4ee4a1e108af044b449edcdfb818c2f55aefd64f0af76b347da16d
diff --git a/dhall-lang/tests/semantic-hash/success/simple/listBuildA.dhall b/dhall-lang/tests/semantic-hash/success/simple/listBuildA.dhall
new file mode 100644
index 0000000..ce0da1a
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/listBuildA.dhall
@@ -0,0 +1,22 @@
+{ example0 =
+ List/build
+ Bool
+ ( λ(list : Type)
+ → λ(cons : Bool → list → list)
+ → λ(nil : list)
+ → cons True (cons False nil)
+ )
+, example1 =
+ List/build
+ Bool
+ (λ(x : Type) → λ(x : Bool → x → x) → λ(x : x@1) → x@1 True (x@1 False x))
+, example2 =
+ λ(id : ∀(a : Type) → a → a)
+ → List/build
+ Bool
+ ( λ(list : Type)
+ → λ(cons : Bool → list → list)
+ → λ(nil : list)
+ → id list (cons True (cons False nil))
+ )
+}
diff --git a/dhall-lang/tests/semantic-hash/success/simple/listBuildB.hash b/dhall-lang/tests/semantic-hash/success/simple/listBuildB.hash
new file mode 100644
index 0000000..2ca996f
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/listBuildB.hash
@@ -0,0 +1 @@
+sha256:f8f03d5be6563b275253b4d995499e783112ff98ed231855e9152ba45970f8c7
diff --git a/dhall-lang/tests/semantic-hash/success/simple/multiLineA.dhall b/dhall-lang/tests/semantic-hash/success/simple/multiLineA.dhall
new file mode 100644
index 0000000..3df6c28
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/multiLineA.dhall
@@ -0,0 +1,4 @@
+''
+ foo
+bar
+''
diff --git a/dhall-lang/tests/semantic-hash/success/simple/multiLineB.hash b/dhall-lang/tests/semantic-hash/success/simple/multiLineB.hash
new file mode 100644
index 0000000..53df846
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/multiLineB.hash
@@ -0,0 +1 @@
+sha256:2ab4fb081094ad6729186b7cd8a0ec67f7845bbea59ec5a484bff2de42390137
diff --git a/dhall-lang/tests/semantic-hash/success/simple/naturalBuildA.dhall b/dhall-lang/tests/semantic-hash/success/simple/naturalBuildA.dhall
new file mode 100644
index 0000000..fd204c5
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/naturalBuildA.dhall
@@ -0,0 +1,18 @@
+{ example0 =
+ Natural/build
+ ( λ(natural : Type)
+ → λ(succ : natural → natural)
+ → λ(zero : natural)
+ → succ zero
+ )
+, example1 =
+ Natural/build (λ(x : Type) → λ(x : x → x) → λ(x : x@1) → x@1 x)
+, example2 =
+ λ(id : ∀(a : Type) → a → a)
+ → Natural/build
+ ( λ(natural : Type)
+ → λ(succ : natural → natural)
+ → λ(zero : natural)
+ → id natural (succ zero)
+ )
+}
diff --git a/dhall-lang/tests/semantic-hash/success/simple/naturalBuildB.hash b/dhall-lang/tests/semantic-hash/success/simple/naturalBuildB.hash
new file mode 100644
index 0000000..7516b0a
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/naturalBuildB.hash
@@ -0,0 +1 @@
+sha256:3e14f3cbed2ddcc78cb9bf66bf2372c2059fd6c4b406ca309a05b89b7f62b011
diff --git a/dhall-lang/tests/semantic-hash/success/simple/naturalPlusA.dhall b/dhall-lang/tests/semantic-hash/success/simple/naturalPlusA.dhall
new file mode 100644
index 0000000..e0ef584
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/naturalPlusA.dhall
@@ -0,0 +1 @@
+1 + 2
diff --git a/dhall-lang/tests/semantic-hash/success/simple/naturalPlusB.hash b/dhall-lang/tests/semantic-hash/success/simple/naturalPlusB.hash
new file mode 100644
index 0000000..ba88e0f
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/naturalPlusB.hash
@@ -0,0 +1 @@
+sha256:15f52ecf91c94c1baac02d5a4964b2ed8fa401641a2c8a95e8306ec7c1e3b8d2
diff --git a/dhall-lang/tests/semantic-hash/success/simple/naturalShowA.dhall b/dhall-lang/tests/semantic-hash/success/simple/naturalShowA.dhall
new file mode 100644
index 0000000..23d8fa5
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/naturalShowA.dhall
@@ -0,0 +1 @@
+Natural/show 42
diff --git a/dhall-lang/tests/semantic-hash/success/simple/naturalShowB.hash b/dhall-lang/tests/semantic-hash/success/simple/naturalShowB.hash
new file mode 100644
index 0000000..158bd7b
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/naturalShowB.hash
@@ -0,0 +1 @@
+sha256:3d1abfe685ff9abcf5e1a6bcce9b1a8374fc8ac176c22ef3e0188bd29e7d8c6d
diff --git a/dhall-lang/tests/semantic-hash/success/simple/naturalToIntegerA.dhall b/dhall-lang/tests/semantic-hash/success/simple/naturalToIntegerA.dhall
new file mode 100644
index 0000000..0a5ce42
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/naturalToIntegerA.dhall
@@ -0,0 +1 @@
+Natural/toInteger 1
diff --git a/dhall-lang/tests/semantic-hash/success/simple/naturalToIntegerB.hash b/dhall-lang/tests/semantic-hash/success/simple/naturalToIntegerB.hash
new file mode 100644
index 0000000..926efe4
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/naturalToIntegerB.hash
@@ -0,0 +1 @@
+sha256:d2cbb0e226f332ea76d63b3ae4332780c4051d1388d3e190debd5441f4595a04
diff --git a/dhall-lang/tests/semantic-hash/success/simple/optionalBuildA.dhall b/dhall-lang/tests/semantic-hash/success/simple/optionalBuildA.dhall
new file mode 100644
index 0000000..f1555fd
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/optionalBuildA.dhall
@@ -0,0 +1,32 @@
+{ example0 =
+ Optional/build
+ Natural
+ ( λ(optional : Type)
+ → λ(just : Natural → optional)
+ → λ(nothing : optional)
+ → just 1
+ )
+, example1 =
+ Optional/build
+ Integer
+ (λ(optional : Type) → λ(x : Integer → optional) → λ(x : optional) → x@1 +1)
+, example2 =
+ λ(id : ∀(a : Type) → a → a)
+ → Optional/build
+ Bool
+ ( λ(optional : Type)
+ → λ(just : Bool → optional)
+ → λ(nothing : optional)
+ → id optional (just True)
+ )
+, example3 =
+ λ(a : Type)
+ → λ(x : a)
+ → Optional/build
+ a
+ ( λ(optional : Type)
+ → λ(just : a → optional)
+ → λ(nothing : optional)
+ → just x
+ )
+}
diff --git a/dhall-lang/tests/semantic-hash/success/simple/optionalBuildB.hash b/dhall-lang/tests/semantic-hash/success/simple/optionalBuildB.hash
new file mode 100644
index 0000000..55addd7
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/optionalBuildB.hash
@@ -0,0 +1 @@
+sha256:57937e066a166baf3d712e744d9aec91894f14d7b25138a6f60c7b7577cc986b
diff --git a/dhall-lang/tests/semantic-hash/success/simple/optionalBuildFoldA.dhall b/dhall-lang/tests/semantic-hash/success/simple/optionalBuildFoldA.dhall
new file mode 100644
index 0000000..eb5ec6c
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/optionalBuildFoldA.dhall
@@ -0,0 +1 @@
+Optional/build Text (Optional/fold Text (Some "foo"))
diff --git a/dhall-lang/tests/semantic-hash/success/simple/optionalBuildFoldB.hash b/dhall-lang/tests/semantic-hash/success/simple/optionalBuildFoldB.hash
new file mode 100644
index 0000000..00e4e49
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/optionalBuildFoldB.hash
@@ -0,0 +1 @@
+sha256:29dc3b0c8df03521d3bb92d3b7d996a70a5dbca8de8607ffaf9f888a2213e73b
diff --git a/dhall-lang/tests/semantic-hash/success/simple/optionalFoldA.dhall b/dhall-lang/tests/semantic-hash/success/simple/optionalFoldA.dhall
new file mode 100644
index 0000000..effc286
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/optionalFoldA.dhall
@@ -0,0 +1,7 @@
+ let f =
+ λ(o : Optional Text)
+ → Optional/fold Text o Natural (λ(j : Text) → 1) 2
+
+in { example0 = f (Some "foo")
+ , example1 = f (None Text)
+ }
diff --git a/dhall-lang/tests/semantic-hash/success/simple/optionalFoldB.hash b/dhall-lang/tests/semantic-hash/success/simple/optionalFoldB.hash
new file mode 100644
index 0000000..fbf68a8
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/optionalFoldB.hash
@@ -0,0 +1 @@
+sha256:225b0c8ffa394c837aebfce636806e3f39511d87331b6ef734311689a2ec8a7e
diff --git a/dhall-lang/tests/semantic-hash/success/simple/sortOperatorA.dhall b/dhall-lang/tests/semantic-hash/success/simple/sortOperatorA.dhall
new file mode 100644
index 0000000..e201b8d
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/sortOperatorA.dhall
@@ -0,0 +1 @@
+{ b = 2 } // { a = 1 }
diff --git a/dhall-lang/tests/semantic-hash/success/simple/sortOperatorB.hash b/dhall-lang/tests/semantic-hash/success/simple/sortOperatorB.hash
new file mode 100644
index 0000000..e61d415
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simple/sortOperatorB.hash
@@ -0,0 +1 @@
+sha256:97090822fa42ff0245484a518e2457f85271f4c36fc9462b82498d85b2cc98fc
diff --git a/dhall-lang/tests/semantic-hash/success/simplifications/andA.dhall b/dhall-lang/tests/semantic-hash/success/simplifications/andA.dhall
new file mode 100644
index 0000000..fbd8011
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simplifications/andA.dhall
@@ -0,0 +1,6 @@
+{ example0 = λ(x : Bool) → x && True
+, example1 = λ(x : Bool) → True && x
+, example2 = λ(x : Bool) → x && False
+, example3 = λ(x : Bool) → False && x
+, example4 = λ(x : Bool) → x && x
+}
diff --git a/dhall-lang/tests/semantic-hash/success/simplifications/andB.hash b/dhall-lang/tests/semantic-hash/success/simplifications/andB.hash
new file mode 100644
index 0000000..b3c7cd6
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simplifications/andB.hash
@@ -0,0 +1 @@
+sha256:ceac399e820b2a86c65077e07e77bb62f10253fda02a51e438457adf4368b580
diff --git a/dhall-lang/tests/semantic-hash/success/simplifications/eqA.dhall b/dhall-lang/tests/semantic-hash/success/simplifications/eqA.dhall
new file mode 100644
index 0000000..39bcdf6
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simplifications/eqA.dhall
@@ -0,0 +1,4 @@
+{ example0 = λ(x : Bool) → x == True
+, example1 = λ(x : Bool) → True == x
+, example2 = λ(x : Bool) → x == x
+}
diff --git a/dhall-lang/tests/semantic-hash/success/simplifications/eqB.hash b/dhall-lang/tests/semantic-hash/success/simplifications/eqB.hash
new file mode 100644
index 0000000..8a830c2
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simplifications/eqB.hash
@@ -0,0 +1 @@
+sha256:5524bd7e3ecdeaa98a25f51f40a1cb33896c2e3e0e21e14c939d17dac946fa4d
diff --git a/dhall-lang/tests/semantic-hash/success/simplifications/ifThenElseA.dhall b/dhall-lang/tests/semantic-hash/success/simplifications/ifThenElseA.dhall
new file mode 100644
index 0000000..33cbad2
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simplifications/ifThenElseA.dhall
@@ -0,0 +1,3 @@
+{ example0 = λ(x : Bool) → if x then True else False
+, example1 = λ(x : Bool) → λ(y : Text) → if x then y else y
+}
diff --git a/dhall-lang/tests/semantic-hash/success/simplifications/ifThenElseB.hash b/dhall-lang/tests/semantic-hash/success/simplifications/ifThenElseB.hash
new file mode 100644
index 0000000..a5437cd
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simplifications/ifThenElseB.hash
@@ -0,0 +1 @@
+sha256:40b3cdc4cc8f2ff9b733e5e8d8613ec8c3d17fc11f22cfd96d8109765c15add5
diff --git a/dhall-lang/tests/semantic-hash/success/simplifications/neA.dhall b/dhall-lang/tests/semantic-hash/success/simplifications/neA.dhall
new file mode 100644
index 0000000..c9d97a0
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simplifications/neA.dhall
@@ -0,0 +1,4 @@
+{ example0 = λ(x : Bool) → x != False
+, example1 = λ(x : Bool) → False != x
+, example2 = λ(x : Bool) → x != x
+}
diff --git a/dhall-lang/tests/semantic-hash/success/simplifications/neB.hash b/dhall-lang/tests/semantic-hash/success/simplifications/neB.hash
new file mode 100644
index 0000000..39b8451
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simplifications/neB.hash
@@ -0,0 +1 @@
+sha256:69d11e754a064f8abe927e5df446896372a6367135e08c52b5c2274e3bd03bc7
diff --git a/dhall-lang/tests/semantic-hash/success/simplifications/orA.dhall b/dhall-lang/tests/semantic-hash/success/simplifications/orA.dhall
new file mode 100644
index 0000000..a919804
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simplifications/orA.dhall
@@ -0,0 +1,6 @@
+{ example0 = λ(x : Bool) → x || True
+, example1 = λ(x : Bool) → True || x
+, example2 = λ(x : Bool) → x || False
+, example3 = λ(x : Bool) → False || x
+, example4 = λ(x : Bool) → x || x
+}
diff --git a/dhall-lang/tests/semantic-hash/success/simplifications/orB.hash b/dhall-lang/tests/semantic-hash/success/simplifications/orB.hash
new file mode 100644
index 0000000..410e10e
--- /dev/null
+++ b/dhall-lang/tests/semantic-hash/success/simplifications/orB.hash
@@ -0,0 +1 @@
+sha256:41437a8eb5753b2d340fc27cc192265459da57cd65d487447a261f2eede2f5ef
diff --git a/dhall-lang/tests/type-inference/success/simple/alternativesAreTypesA.dhall b/dhall-lang/tests/type-inference/success/simple/alternativesAreTypesA.dhall
new file mode 100644
index 0000000..9b32d26
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/simple/alternativesAreTypesA.dhall
@@ -0,0 +1 @@
+< Left = List | Right : Type >
diff --git a/dhall-lang/tests/type-inference/success/simple/alternativesAreTypesB.dhall b/dhall-lang/tests/type-inference/success/simple/alternativesAreTypesB.dhall
new file mode 100644
index 0000000..bc6f4df
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/simple/alternativesAreTypesB.dhall
@@ -0,0 +1 @@
+< Left : Type → Type | Right : Type >
diff --git a/dhall-lang/tests/type-inference/success/simple/kindParameterA.dhall b/dhall-lang/tests/type-inference/success/simple/kindParameterA.dhall
new file mode 100644
index 0000000..2123ba2
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/simple/kindParameterA.dhall
@@ -0,0 +1 @@
+λ(k : Kind) → λ(a : k → k → Type) → λ(x : k) → a x
diff --git a/dhall-lang/tests/type-inference/success/simple/kindParameterB.dhall b/dhall-lang/tests/type-inference/success/simple/kindParameterB.dhall
new file mode 100644
index 0000000..95781e3
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/simple/kindParameterB.dhall
@@ -0,0 +1 @@
+∀(k : Kind) → ∀(a : k → k → Type) → ∀(x : k) → k → Type
diff --git a/dhall-lang/tests/type-inference/success/unit/BoolA.dhall b/dhall-lang/tests/type-inference/success/unit/BoolA.dhall
new file mode 100644
index 0000000..13b3e87
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/BoolA.dhall
@@ -0,0 +1 @@
+Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/BoolB.dhall b/dhall-lang/tests/type-inference/success/unit/BoolB.dhall
new file mode 100644
index 0000000..245bc9d
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/BoolB.dhall
@@ -0,0 +1 @@
+Type
diff --git a/dhall-lang/tests/type-inference/success/unit/DoubleA.dhall b/dhall-lang/tests/type-inference/success/unit/DoubleA.dhall
new file mode 100644
index 0000000..2725edd
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/DoubleA.dhall
@@ -0,0 +1 @@
+Double
diff --git a/dhall-lang/tests/type-inference/success/unit/DoubleB.dhall b/dhall-lang/tests/type-inference/success/unit/DoubleB.dhall
new file mode 100644
index 0000000..245bc9d
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/DoubleB.dhall
@@ -0,0 +1 @@
+Type
diff --git a/dhall-lang/tests/type-inference/success/unit/DoubleLiteralA.dhall b/dhall-lang/tests/type-inference/success/unit/DoubleLiteralA.dhall
new file mode 100644
index 0000000..d3827e7
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/DoubleLiteralA.dhall
@@ -0,0 +1 @@
+1.0
diff --git a/dhall-lang/tests/type-inference/success/unit/DoubleLiteralB.dhall b/dhall-lang/tests/type-inference/success/unit/DoubleLiteralB.dhall
new file mode 100644
index 0000000..2725edd
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/DoubleLiteralB.dhall
@@ -0,0 +1 @@
+Double
diff --git a/dhall-lang/tests/type-inference/success/unit/DoubleShowA.dhall b/dhall-lang/tests/type-inference/success/unit/DoubleShowA.dhall
new file mode 100644
index 0000000..3aed5b0
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/DoubleShowA.dhall
@@ -0,0 +1 @@
+Double/show
diff --git a/dhall-lang/tests/type-inference/success/unit/DoubleShowB.dhall b/dhall-lang/tests/type-inference/success/unit/DoubleShowB.dhall
new file mode 100644
index 0000000..667a6a4
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/DoubleShowB.dhall
@@ -0,0 +1 @@
+Double → Text
diff --git a/dhall-lang/tests/type-inference/success/unit/FalseA.dhall b/dhall-lang/tests/type-inference/success/unit/FalseA.dhall
new file mode 100644
index 0000000..bc59c12
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/FalseA.dhall
@@ -0,0 +1 @@
+False
diff --git a/dhall-lang/tests/type-inference/success/unit/FalseB.dhall b/dhall-lang/tests/type-inference/success/unit/FalseB.dhall
new file mode 100644
index 0000000..13b3e87
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/FalseB.dhall
@@ -0,0 +1 @@
+Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/FunctionA.dhall b/dhall-lang/tests/type-inference/success/unit/FunctionA.dhall
new file mode 100644
index 0000000..2b12aae
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/FunctionA.dhall
@@ -0,0 +1 @@
+λ(_ : Bool) → _
diff --git a/dhall-lang/tests/type-inference/success/unit/FunctionApplicationA.dhall b/dhall-lang/tests/type-inference/success/unit/FunctionApplicationA.dhall
new file mode 100644
index 0000000..0b024ce
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/FunctionApplicationA.dhall
@@ -0,0 +1 @@
+(λ(_ : Bool) → _) True
diff --git a/dhall-lang/tests/type-inference/success/unit/FunctionApplicationB.dhall b/dhall-lang/tests/type-inference/success/unit/FunctionApplicationB.dhall
new file mode 100644
index 0000000..13b3e87
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/FunctionApplicationB.dhall
@@ -0,0 +1 @@
+Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/FunctionB.dhall b/dhall-lang/tests/type-inference/success/unit/FunctionB.dhall
new file mode 100644
index 0000000..4dc08b3
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/FunctionB.dhall
@@ -0,0 +1 @@
+Bool → Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/FunctionNamedArgA.dhall b/dhall-lang/tests/type-inference/success/unit/FunctionNamedArgA.dhall
new file mode 100644
index 0000000..fb11503
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/FunctionNamedArgA.dhall
@@ -0,0 +1 @@
+λ(x : Bool) → x
diff --git a/dhall-lang/tests/type-inference/success/unit/FunctionNamedArgB.dhall b/dhall-lang/tests/type-inference/success/unit/FunctionNamedArgB.dhall
new file mode 100644
index 0000000..c11b59c
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/FunctionNamedArgB.dhall
@@ -0,0 +1 @@
+∀(x : Bool) → Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/FunctionTypeKindKindA.dhall b/dhall-lang/tests/type-inference/success/unit/FunctionTypeKindKindA.dhall
new file mode 100644
index 0000000..a42b4a7
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/FunctionTypeKindKindA.dhall
@@ -0,0 +1 @@
+Kind → Kind
diff --git a/dhall-lang/tests/type-inference/success/unit/FunctionTypeKindKindB.dhall b/dhall-lang/tests/type-inference/success/unit/FunctionTypeKindKindB.dhall
new file mode 100644
index 0000000..9b48bbb
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/FunctionTypeKindKindB.dhall
@@ -0,0 +1 @@
+Sort
diff --git a/dhall-lang/tests/type-inference/success/unit/FunctionTypeKindTermA.dhall b/dhall-lang/tests/type-inference/success/unit/FunctionTypeKindTermA.dhall
new file mode 100644
index 0000000..e943d4e
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/FunctionTypeKindTermA.dhall
@@ -0,0 +1 @@
+Kind → Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/FunctionTypeKindTermB.dhall b/dhall-lang/tests/type-inference/success/unit/FunctionTypeKindTermB.dhall
new file mode 100644
index 0000000..245bc9d
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/FunctionTypeKindTermB.dhall
@@ -0,0 +1 @@
+Type
diff --git a/dhall-lang/tests/type-inference/success/unit/FunctionTypeKindTypeA.dhall b/dhall-lang/tests/type-inference/success/unit/FunctionTypeKindTypeA.dhall
new file mode 100644
index 0000000..cad6fda
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/FunctionTypeKindTypeA.dhall
@@ -0,0 +1 @@
+Kind → Type
diff --git a/dhall-lang/tests/type-inference/success/unit/FunctionTypeKindTypeB.dhall b/dhall-lang/tests/type-inference/success/unit/FunctionTypeKindTypeB.dhall
new file mode 100644
index 0000000..9b48bbb
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/FunctionTypeKindTypeB.dhall
@@ -0,0 +1 @@
+Sort
diff --git a/dhall-lang/tests/type-inference/success/unit/FunctionTypeTermTermA.dhall b/dhall-lang/tests/type-inference/success/unit/FunctionTypeTermTermA.dhall
new file mode 100644
index 0000000..4dc08b3
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/FunctionTypeTermTermA.dhall
@@ -0,0 +1 @@
+Bool → Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/FunctionTypeTermTermB.dhall b/dhall-lang/tests/type-inference/success/unit/FunctionTypeTermTermB.dhall
new file mode 100644
index 0000000..245bc9d
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/FunctionTypeTermTermB.dhall
@@ -0,0 +1 @@
+Type
diff --git a/dhall-lang/tests/type-inference/success/unit/FunctionTypeTypeTermA.dhall b/dhall-lang/tests/type-inference/success/unit/FunctionTypeTypeTermA.dhall
new file mode 100644
index 0000000..888a047
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/FunctionTypeTypeTermA.dhall
@@ -0,0 +1 @@
+Type → Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/FunctionTypeTypeTermB.dhall b/dhall-lang/tests/type-inference/success/unit/FunctionTypeTypeTermB.dhall
new file mode 100644
index 0000000..245bc9d
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/FunctionTypeTypeTermB.dhall
@@ -0,0 +1 @@
+Type
diff --git a/dhall-lang/tests/type-inference/success/unit/FunctionTypeTypeTypeA.dhall b/dhall-lang/tests/type-inference/success/unit/FunctionTypeTypeTypeA.dhall
new file mode 100644
index 0000000..95883c7
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/FunctionTypeTypeTypeA.dhall
@@ -0,0 +1 @@
+Type → Type
diff --git a/dhall-lang/tests/type-inference/success/unit/FunctionTypeTypeTypeB.dhall b/dhall-lang/tests/type-inference/success/unit/FunctionTypeTypeTypeB.dhall
new file mode 100644
index 0000000..894beeb
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/FunctionTypeTypeTypeB.dhall
@@ -0,0 +1 @@
+Kind
diff --git a/dhall-lang/tests/type-inference/success/unit/FunctionTypeUsingArgumentA.dhall b/dhall-lang/tests/type-inference/success/unit/FunctionTypeUsingArgumentA.dhall
new file mode 100644
index 0000000..1803a6e
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/FunctionTypeUsingArgumentA.dhall
@@ -0,0 +1 @@
+Type → _
diff --git a/dhall-lang/tests/type-inference/success/unit/FunctionTypeUsingArgumentB.dhall b/dhall-lang/tests/type-inference/success/unit/FunctionTypeUsingArgumentB.dhall
new file mode 100644
index 0000000..245bc9d
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/FunctionTypeUsingArgumentB.dhall
@@ -0,0 +1 @@
+Type
diff --git a/dhall-lang/tests/type-inference/success/unit/IfA.dhall b/dhall-lang/tests/type-inference/success/unit/IfA.dhall
new file mode 100644
index 0000000..53f5b4d
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/IfA.dhall
@@ -0,0 +1 @@
+if True then False else True
diff --git a/dhall-lang/tests/type-inference/success/unit/IfB.dhall b/dhall-lang/tests/type-inference/success/unit/IfB.dhall
new file mode 100644
index 0000000..13b3e87
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/IfB.dhall
@@ -0,0 +1 @@
+Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/IfNormalizeArgumentsA.dhall b/dhall-lang/tests/type-inference/success/unit/IfNormalizeArgumentsA.dhall
new file mode 100644
index 0000000..1b2af03
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/IfNormalizeArgumentsA.dhall
@@ -0,0 +1,9 @@
+ if if True then True else True
+
+then if True then False else True
+
+else if True
+
+then True
+
+else True
diff --git a/dhall-lang/tests/type-inference/success/unit/IfNormalizeArgumentsB.dhall b/dhall-lang/tests/type-inference/success/unit/IfNormalizeArgumentsB.dhall
new file mode 100644
index 0000000..13b3e87
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/IfNormalizeArgumentsB.dhall
@@ -0,0 +1 @@
+Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/IntegerA.dhall b/dhall-lang/tests/type-inference/success/unit/IntegerA.dhall
new file mode 100644
index 0000000..a48c214
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/IntegerA.dhall
@@ -0,0 +1 @@
+Integer
diff --git a/dhall-lang/tests/type-inference/success/unit/IntegerB.dhall b/dhall-lang/tests/type-inference/success/unit/IntegerB.dhall
new file mode 100644
index 0000000..245bc9d
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/IntegerB.dhall
@@ -0,0 +1 @@
+Type
diff --git a/dhall-lang/tests/type-inference/success/unit/IntegerLiteralA.dhall b/dhall-lang/tests/type-inference/success/unit/IntegerLiteralA.dhall
new file mode 100644
index 0000000..556cf17
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/IntegerLiteralA.dhall
@@ -0,0 +1 @@
++1
diff --git a/dhall-lang/tests/type-inference/success/unit/IntegerLiteralB.dhall b/dhall-lang/tests/type-inference/success/unit/IntegerLiteralB.dhall
new file mode 100644
index 0000000..a48c214
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/IntegerLiteralB.dhall
@@ -0,0 +1 @@
+Integer
diff --git a/dhall-lang/tests/type-inference/success/unit/IntegerShowA.dhall b/dhall-lang/tests/type-inference/success/unit/IntegerShowA.dhall
new file mode 100644
index 0000000..e108895
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/IntegerShowA.dhall
@@ -0,0 +1 @@
+Integer/show
diff --git a/dhall-lang/tests/type-inference/success/unit/IntegerShowB.dhall b/dhall-lang/tests/type-inference/success/unit/IntegerShowB.dhall
new file mode 100644
index 0000000..0aea260
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/IntegerShowB.dhall
@@ -0,0 +1 @@
+Integer → Text
diff --git a/dhall-lang/tests/type-inference/success/unit/IntegerToDoubleA.dhall b/dhall-lang/tests/type-inference/success/unit/IntegerToDoubleA.dhall
new file mode 100644
index 0000000..2a72d49
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/IntegerToDoubleA.dhall
@@ -0,0 +1 @@
+Integer/toDouble
diff --git a/dhall-lang/tests/type-inference/success/unit/IntegerToDoubleB.dhall b/dhall-lang/tests/type-inference/success/unit/IntegerToDoubleB.dhall
new file mode 100644
index 0000000..e4fac93
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/IntegerToDoubleB.dhall
@@ -0,0 +1 @@
+Integer → Double
diff --git a/dhall-lang/tests/type-inference/success/unit/KindA.dhall b/dhall-lang/tests/type-inference/success/unit/KindA.dhall
new file mode 100644
index 0000000..894beeb
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/KindA.dhall
@@ -0,0 +1 @@
+Kind
diff --git a/dhall-lang/tests/type-inference/success/unit/KindB.dhall b/dhall-lang/tests/type-inference/success/unit/KindB.dhall
new file mode 100644
index 0000000..9b48bbb
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/KindB.dhall
@@ -0,0 +1 @@
+Sort
diff --git a/dhall-lang/tests/type-inference/success/unit/LetA.dhall b/dhall-lang/tests/type-inference/success/unit/LetA.dhall
new file mode 100644
index 0000000..50829a8
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/LetA.dhall
@@ -0,0 +1 @@
+let x = True in x
diff --git a/dhall-lang/tests/type-inference/success/unit/LetB.dhall b/dhall-lang/tests/type-inference/success/unit/LetB.dhall
new file mode 100644
index 0000000..13b3e87
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/LetB.dhall
@@ -0,0 +1 @@
+Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/LetNestedTypeSynonymA.dhall b/dhall-lang/tests/type-inference/success/unit/LetNestedTypeSynonymA.dhall
new file mode 100644
index 0000000..a3f1d92
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/LetNestedTypeSynonymA.dhall
@@ -0,0 +1 @@
+let x = Bool let y : x = True in y
diff --git a/dhall-lang/tests/type-inference/success/unit/LetNestedTypeSynonymB.dhall b/dhall-lang/tests/type-inference/success/unit/LetNestedTypeSynonymB.dhall
new file mode 100644
index 0000000..13b3e87
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/LetNestedTypeSynonymB.dhall
@@ -0,0 +1 @@
+Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/LetTypeSynonymA.dhall b/dhall-lang/tests/type-inference/success/unit/LetTypeSynonymA.dhall
new file mode 100644
index 0000000..1ff7b02
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/LetTypeSynonymA.dhall
@@ -0,0 +1 @@
+let x = Bool in True : x
diff --git a/dhall-lang/tests/type-inference/success/unit/LetTypeSynonymB.dhall b/dhall-lang/tests/type-inference/success/unit/LetTypeSynonymB.dhall
new file mode 100644
index 0000000..13b3e87
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/LetTypeSynonymB.dhall
@@ -0,0 +1 @@
+Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/LetWithAnnotationA.dhall b/dhall-lang/tests/type-inference/success/unit/LetWithAnnotationA.dhall
new file mode 100644
index 0000000..4319f47
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/LetWithAnnotationA.dhall
@@ -0,0 +1 @@
+let x : Bool = True in x
diff --git a/dhall-lang/tests/type-inference/success/unit/LetWithAnnotationB.dhall b/dhall-lang/tests/type-inference/success/unit/LetWithAnnotationB.dhall
new file mode 100644
index 0000000..13b3e87
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/LetWithAnnotationB.dhall
@@ -0,0 +1 @@
+Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/ListA.dhall b/dhall-lang/tests/type-inference/success/unit/ListA.dhall
new file mode 100644
index 0000000..d6a7fe7
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/ListA.dhall
@@ -0,0 +1 @@
+List
diff --git a/dhall-lang/tests/type-inference/success/unit/ListB.dhall b/dhall-lang/tests/type-inference/success/unit/ListB.dhall
new file mode 100644
index 0000000..95883c7
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/ListB.dhall
@@ -0,0 +1 @@
+Type → Type
diff --git a/dhall-lang/tests/type-inference/success/unit/ListBuildA.dhall b/dhall-lang/tests/type-inference/success/unit/ListBuildA.dhall
new file mode 100644
index 0000000..9616576
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/ListBuildA.dhall
@@ -0,0 +1 @@
+List/build
diff --git a/dhall-lang/tests/type-inference/success/unit/ListBuildB.dhall b/dhall-lang/tests/type-inference/success/unit/ListBuildB.dhall
new file mode 100644
index 0000000..a423a17
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/ListBuildB.dhall
@@ -0,0 +1,3 @@
+ ∀(a : Type)
+→ (∀(list : Type) → ∀(cons : a → list → list) → ∀(nil : list) → list)
+→ List a
diff --git a/dhall-lang/tests/type-inference/success/unit/ListFoldA.dhall b/dhall-lang/tests/type-inference/success/unit/ListFoldA.dhall
new file mode 100644
index 0000000..c037121
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/ListFoldA.dhall
@@ -0,0 +1 @@
+List/fold
diff --git a/dhall-lang/tests/type-inference/success/unit/ListFoldB.dhall b/dhall-lang/tests/type-inference/success/unit/ListFoldB.dhall
new file mode 100644
index 0000000..3a2fba4
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/ListFoldB.dhall
@@ -0,0 +1,6 @@
+ ∀(a : Type)
+→ List a
+→ ∀(list : Type)
+→ ∀(cons : a → list → list)
+→ ∀(nil : list)
+→ list
diff --git a/dhall-lang/tests/type-inference/success/unit/ListHeadA.dhall b/dhall-lang/tests/type-inference/success/unit/ListHeadA.dhall
new file mode 100644
index 0000000..c42f9de
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/ListHeadA.dhall
@@ -0,0 +1 @@
+List/head
diff --git a/dhall-lang/tests/type-inference/success/unit/ListHeadB.dhall b/dhall-lang/tests/type-inference/success/unit/ListHeadB.dhall
new file mode 100644
index 0000000..917deb9
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/ListHeadB.dhall
@@ -0,0 +1 @@
+∀(a : Type) → List a → Optional a
diff --git a/dhall-lang/tests/type-inference/success/unit/ListIndexedA.dhall b/dhall-lang/tests/type-inference/success/unit/ListIndexedA.dhall
new file mode 100644
index 0000000..5aa6b92
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/ListIndexedA.dhall
@@ -0,0 +1 @@
+List/indexed
diff --git a/dhall-lang/tests/type-inference/success/unit/ListIndexedB.dhall b/dhall-lang/tests/type-inference/success/unit/ListIndexedB.dhall
new file mode 100644
index 0000000..3ce7924
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/ListIndexedB.dhall
@@ -0,0 +1 @@
+∀(a : Type) → List a → List { index : Natural, value : a }
diff --git a/dhall-lang/tests/type-inference/success/unit/ListLastA.dhall b/dhall-lang/tests/type-inference/success/unit/ListLastA.dhall
new file mode 100644
index 0000000..0c8be9d
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/ListLastA.dhall
@@ -0,0 +1 @@
+List/last
diff --git a/dhall-lang/tests/type-inference/success/unit/ListLastB.dhall b/dhall-lang/tests/type-inference/success/unit/ListLastB.dhall
new file mode 100644
index 0000000..917deb9
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/ListLastB.dhall
@@ -0,0 +1 @@
+∀(a : Type) → List a → Optional a
diff --git a/dhall-lang/tests/type-inference/success/unit/ListLengthA.dhall b/dhall-lang/tests/type-inference/success/unit/ListLengthA.dhall
new file mode 100644
index 0000000..b2f6b92
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/ListLengthA.dhall
@@ -0,0 +1 @@
+List/length
diff --git a/dhall-lang/tests/type-inference/success/unit/ListLengthB.dhall b/dhall-lang/tests/type-inference/success/unit/ListLengthB.dhall
new file mode 100644
index 0000000..d8dc21b
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/ListLengthB.dhall
@@ -0,0 +1 @@
+∀(a : Type) → List a → Natural
diff --git a/dhall-lang/tests/type-inference/success/unit/ListLiteralEmptyA.dhall b/dhall-lang/tests/type-inference/success/unit/ListLiteralEmptyA.dhall
new file mode 100644
index 0000000..3b99552
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/ListLiteralEmptyA.dhall
@@ -0,0 +1 @@
+[] : List Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/ListLiteralEmptyB.dhall b/dhall-lang/tests/type-inference/success/unit/ListLiteralEmptyB.dhall
new file mode 100644
index 0000000..f5dc179
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/ListLiteralEmptyB.dhall
@@ -0,0 +1 @@
+List Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/ListLiteralEmptyNormalizeAnnotationA.dhall b/dhall-lang/tests/type-inference/success/unit/ListLiteralEmptyNormalizeAnnotationA.dhall
new file mode 100644
index 0000000..ba59ac6
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/ListLiteralEmptyNormalizeAnnotationA.dhall
@@ -0,0 +1 @@
+[] : { x = List Bool }.x
diff --git a/dhall-lang/tests/type-inference/success/unit/ListLiteralEmptyNormalizeAnnotationB.dhall b/dhall-lang/tests/type-inference/success/unit/ListLiteralEmptyNormalizeAnnotationB.dhall
new file mode 100644
index 0000000..f5dc179
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/ListLiteralEmptyNormalizeAnnotationB.dhall
@@ -0,0 +1 @@
+List Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/ListLiteralNormalizeArgumentsA.dhall b/dhall-lang/tests/type-inference/success/unit/ListLiteralNormalizeArgumentsA.dhall
new file mode 100644
index 0000000..9821ddf
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/ListLiteralNormalizeArgumentsA.dhall
@@ -0,0 +1 @@
+[ if True then False else True ]
diff --git a/dhall-lang/tests/type-inference/success/unit/ListLiteralNormalizeArgumentsB.dhall b/dhall-lang/tests/type-inference/success/unit/ListLiteralNormalizeArgumentsB.dhall
new file mode 100644
index 0000000..f5dc179
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/ListLiteralNormalizeArgumentsB.dhall
@@ -0,0 +1 @@
+List Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/ListLiteralOneA.dhall b/dhall-lang/tests/type-inference/success/unit/ListLiteralOneA.dhall
new file mode 100644
index 0000000..bc1817c
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/ListLiteralOneA.dhall
@@ -0,0 +1 @@
+[ True ]
diff --git a/dhall-lang/tests/type-inference/success/unit/ListLiteralOneB.dhall b/dhall-lang/tests/type-inference/success/unit/ListLiteralOneB.dhall
new file mode 100644
index 0000000..f5dc179
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/ListLiteralOneB.dhall
@@ -0,0 +1 @@
+List Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/ListReverseA.dhall b/dhall-lang/tests/type-inference/success/unit/ListReverseA.dhall
new file mode 100644
index 0000000..d7fe946
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/ListReverseA.dhall
@@ -0,0 +1 @@
+List/reverse
diff --git a/dhall-lang/tests/type-inference/success/unit/ListReverseB.dhall b/dhall-lang/tests/type-inference/success/unit/ListReverseB.dhall
new file mode 100644
index 0000000..515726c
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/ListReverseB.dhall
@@ -0,0 +1 @@
+∀(a : Type) → List a → List a
diff --git a/dhall-lang/tests/type-inference/success/unit/MergeEmptyUnionA.dhall b/dhall-lang/tests/type-inference/success/unit/MergeEmptyUnionA.dhall
new file mode 100644
index 0000000..383b3e8
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/MergeEmptyUnionA.dhall
@@ -0,0 +1 @@
+λ(x : <>) → merge {=} x : Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/MergeEmptyUnionB.dhall b/dhall-lang/tests/type-inference/success/unit/MergeEmptyUnionB.dhall
new file mode 100644
index 0000000..6ae26e7
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/MergeEmptyUnionB.dhall
@@ -0,0 +1 @@
+∀(x : <>) → Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/MergeOneA.dhall b/dhall-lang/tests/type-inference/success/unit/MergeOneA.dhall
new file mode 100644
index 0000000..472a414
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/MergeOneA.dhall
@@ -0,0 +1 @@
+merge { x = λ(_ : Bool) → _ } (< x : Bool >.x True)
diff --git a/dhall-lang/tests/type-inference/success/unit/MergeOneB.dhall b/dhall-lang/tests/type-inference/success/unit/MergeOneB.dhall
new file mode 100644
index 0000000..13b3e87
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/MergeOneB.dhall
@@ -0,0 +1 @@
+Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/MergeOneEmptyA.dhall b/dhall-lang/tests/type-inference/success/unit/MergeOneEmptyA.dhall
new file mode 100644
index 0000000..a74daf9
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/MergeOneEmptyA.dhall
@@ -0,0 +1 @@
+merge { x = 5 } < x >.x
diff --git a/dhall-lang/tests/type-inference/success/unit/MergeOneEmptyB.dhall b/dhall-lang/tests/type-inference/success/unit/MergeOneEmptyB.dhall
new file mode 100644
index 0000000..2f184a4
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/MergeOneEmptyB.dhall
@@ -0,0 +1 @@
+Natural
diff --git a/dhall-lang/tests/type-inference/success/unit/MergeOneWithAnnotationA.dhall b/dhall-lang/tests/type-inference/success/unit/MergeOneWithAnnotationA.dhall
new file mode 100644
index 0000000..b55cd8a
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/MergeOneWithAnnotationA.dhall
@@ -0,0 +1 @@
+merge { x = λ(_ : Bool) → _ } (< x : Bool >.x True) : Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/MergeOneWithAnnotationB.dhall b/dhall-lang/tests/type-inference/success/unit/MergeOneWithAnnotationB.dhall
new file mode 100644
index 0000000..13b3e87
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/MergeOneWithAnnotationB.dhall
@@ -0,0 +1 @@
+Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/NaturalA.dhall b/dhall-lang/tests/type-inference/success/unit/NaturalA.dhall
new file mode 100644
index 0000000..2f184a4
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/NaturalA.dhall
@@ -0,0 +1 @@
+Natural
diff --git a/dhall-lang/tests/type-inference/success/unit/NaturalB.dhall b/dhall-lang/tests/type-inference/success/unit/NaturalB.dhall
new file mode 100644
index 0000000..245bc9d
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/NaturalB.dhall
@@ -0,0 +1 @@
+Type
diff --git a/dhall-lang/tests/type-inference/success/unit/NaturalBuildA.dhall b/dhall-lang/tests/type-inference/success/unit/NaturalBuildA.dhall
new file mode 100644
index 0000000..d5d9a61
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/NaturalBuildA.dhall
@@ -0,0 +1 @@
+Natural/build
diff --git a/dhall-lang/tests/type-inference/success/unit/NaturalBuildB.dhall b/dhall-lang/tests/type-inference/success/unit/NaturalBuildB.dhall
new file mode 100644
index 0000000..81506bd
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/NaturalBuildB.dhall
@@ -0,0 +1,6 @@
+ ( ∀(natural : Type)
+ → ∀(succ : natural → natural)
+ → ∀(zero : natural)
+ → natural
+ )
+→ Natural
diff --git a/dhall-lang/tests/type-inference/success/unit/NaturalEvenA.dhall b/dhall-lang/tests/type-inference/success/unit/NaturalEvenA.dhall
new file mode 100644
index 0000000..0afe9d1
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/NaturalEvenA.dhall
@@ -0,0 +1 @@
+Natural/even
diff --git a/dhall-lang/tests/type-inference/success/unit/NaturalEvenB.dhall b/dhall-lang/tests/type-inference/success/unit/NaturalEvenB.dhall
new file mode 100644
index 0000000..efb0395
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/NaturalEvenB.dhall
@@ -0,0 +1 @@
+Natural → Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/NaturalFoldA.dhall b/dhall-lang/tests/type-inference/success/unit/NaturalFoldA.dhall
new file mode 100644
index 0000000..8942388
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/NaturalFoldA.dhall
@@ -0,0 +1 @@
+Natural/fold
diff --git a/dhall-lang/tests/type-inference/success/unit/NaturalFoldB.dhall b/dhall-lang/tests/type-inference/success/unit/NaturalFoldB.dhall
new file mode 100644
index 0000000..86fdece
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/NaturalFoldB.dhall
@@ -0,0 +1,5 @@
+ Natural
+→ ∀(natural : Type)
+→ ∀(succ : natural → natural)
+→ ∀(zero : natural)
+→ natural
diff --git a/dhall-lang/tests/type-inference/success/unit/NaturalIsZeroA.dhall b/dhall-lang/tests/type-inference/success/unit/NaturalIsZeroA.dhall
new file mode 100644
index 0000000..35d6b2e
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/NaturalIsZeroA.dhall
@@ -0,0 +1 @@
+Natural/isZero
diff --git a/dhall-lang/tests/type-inference/success/unit/NaturalIsZeroB.dhall b/dhall-lang/tests/type-inference/success/unit/NaturalIsZeroB.dhall
new file mode 100644
index 0000000..efb0395
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/NaturalIsZeroB.dhall
@@ -0,0 +1 @@
+Natural → Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/NaturalLiteralA.dhall b/dhall-lang/tests/type-inference/success/unit/NaturalLiteralA.dhall
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/NaturalLiteralA.dhall
@@ -0,0 +1 @@
+1
diff --git a/dhall-lang/tests/type-inference/success/unit/NaturalLiteralB.dhall b/dhall-lang/tests/type-inference/success/unit/NaturalLiteralB.dhall
new file mode 100644
index 0000000..2f184a4
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/NaturalLiteralB.dhall
@@ -0,0 +1 @@
+Natural
diff --git a/dhall-lang/tests/type-inference/success/unit/NaturalOddA.dhall b/dhall-lang/tests/type-inference/success/unit/NaturalOddA.dhall
new file mode 100644
index 0000000..c214434
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/NaturalOddA.dhall
@@ -0,0 +1 @@
+Natural/odd
diff --git a/dhall-lang/tests/type-inference/success/unit/NaturalOddB.dhall b/dhall-lang/tests/type-inference/success/unit/NaturalOddB.dhall
new file mode 100644
index 0000000..efb0395
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/NaturalOddB.dhall
@@ -0,0 +1 @@
+Natural → Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/NaturalShowA.dhall b/dhall-lang/tests/type-inference/success/unit/NaturalShowA.dhall
new file mode 100644
index 0000000..2c4bdc5
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/NaturalShowA.dhall
@@ -0,0 +1 @@
+Natural/show
diff --git a/dhall-lang/tests/type-inference/success/unit/NaturalShowB.dhall b/dhall-lang/tests/type-inference/success/unit/NaturalShowB.dhall
new file mode 100644
index 0000000..a2b0041
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/NaturalShowB.dhall
@@ -0,0 +1 @@
+Natural → Text
diff --git a/dhall-lang/tests/type-inference/success/unit/NaturalToIntegerA.dhall b/dhall-lang/tests/type-inference/success/unit/NaturalToIntegerA.dhall
new file mode 100644
index 0000000..36992b5
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/NaturalToIntegerA.dhall
@@ -0,0 +1 @@
+Natural/toInteger
diff --git a/dhall-lang/tests/type-inference/success/unit/NaturalToIntegerB.dhall b/dhall-lang/tests/type-inference/success/unit/NaturalToIntegerB.dhall
new file mode 100644
index 0000000..03c0cbd
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/NaturalToIntegerB.dhall
@@ -0,0 +1 @@
+Natural → Integer
diff --git a/dhall-lang/tests/type-inference/success/unit/NoneA.dhall b/dhall-lang/tests/type-inference/success/unit/NoneA.dhall
new file mode 100644
index 0000000..b0047fa
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/NoneA.dhall
@@ -0,0 +1 @@
+None
diff --git a/dhall-lang/tests/type-inference/success/unit/NoneB.dhall b/dhall-lang/tests/type-inference/success/unit/NoneB.dhall
new file mode 100644
index 0000000..5a1027c
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/NoneB.dhall
@@ -0,0 +1 @@
+∀(A : Type) → Optional A
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorAndA.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorAndA.dhall
new file mode 100644
index 0000000..0b1a9b9
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorAndA.dhall
@@ -0,0 +1 @@
+True && False
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorAndB.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorAndB.dhall
new file mode 100644
index 0000000..13b3e87
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorAndB.dhall
@@ -0,0 +1 @@
+Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorAndNormalizeArgumentsA.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorAndNormalizeArgumentsA.dhall
new file mode 100644
index 0000000..1f14a4d
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorAndNormalizeArgumentsA.dhall
@@ -0,0 +1 @@
+True && False && False
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorAndNormalizeArgumentsB.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorAndNormalizeArgumentsB.dhall
new file mode 100644
index 0000000..13b3e87
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorAndNormalizeArgumentsB.dhall
@@ -0,0 +1 @@
+Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorEqualA.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorEqualA.dhall
new file mode 100644
index 0000000..18bc42d
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorEqualA.dhall
@@ -0,0 +1 @@
+True == False
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorEqualB.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorEqualB.dhall
new file mode 100644
index 0000000..13b3e87
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorEqualB.dhall
@@ -0,0 +1 @@
+Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorEqualNormalizeArgumentsA.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorEqualNormalizeArgumentsA.dhall
new file mode 100644
index 0000000..2525e8b
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorEqualNormalizeArgumentsA.dhall
@@ -0,0 +1 @@
+True == False == False
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorEqualNormalizeArgumentsB.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorEqualNormalizeArgumentsB.dhall
new file mode 100644
index 0000000..13b3e87
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorEqualNormalizeArgumentsB.dhall
@@ -0,0 +1 @@
+Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorListConcatenateA.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorListConcatenateA.dhall
new file mode 100644
index 0000000..a515282
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorListConcatenateA.dhall
@@ -0,0 +1 @@
+[ True ] # [ True ]
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorListConcatenateB.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorListConcatenateB.dhall
new file mode 100644
index 0000000..f5dc179
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorListConcatenateB.dhall
@@ -0,0 +1 @@
+List Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorListConcatenateNormalizeArgumentsA.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorListConcatenateNormalizeArgumentsA.dhall
new file mode 100644
index 0000000..4657287
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorListConcatenateNormalizeArgumentsA.dhall
@@ -0,0 +1 @@
+(if True then [ True ] else [ False ]) # (if True then [ True ] else [ False ])
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorListConcatenateNormalizeArgumentsB.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorListConcatenateNormalizeArgumentsB.dhall
new file mode 100644
index 0000000..f5dc179
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorListConcatenateNormalizeArgumentsB.dhall
@@ -0,0 +1 @@
+List Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorNotEqualA.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorNotEqualA.dhall
new file mode 100644
index 0000000..1127fe2
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorNotEqualA.dhall
@@ -0,0 +1 @@
+True != False
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorNotEqualB.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorNotEqualB.dhall
new file mode 100644
index 0000000..13b3e87
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorNotEqualB.dhall
@@ -0,0 +1 @@
+Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorNotEqualNormalizeArgumentsA.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorNotEqualNormalizeArgumentsA.dhall
new file mode 100644
index 0000000..0d44e4e
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorNotEqualNormalizeArgumentsA.dhall
@@ -0,0 +1 @@
+True != False != False
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorNotEqualNormalizeArgumentsB.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorNotEqualNormalizeArgumentsB.dhall
new file mode 100644
index 0000000..13b3e87
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorNotEqualNormalizeArgumentsB.dhall
@@ -0,0 +1 @@
+Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorOrA.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorOrA.dhall
new file mode 100644
index 0000000..9be9945
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorOrA.dhall
@@ -0,0 +1 @@
+True || False
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorOrB.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorOrB.dhall
new file mode 100644
index 0000000..13b3e87
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorOrB.dhall
@@ -0,0 +1 @@
+Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorOrNormalizeArgumentsA.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorOrNormalizeArgumentsA.dhall
new file mode 100644
index 0000000..5ba1a5d
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorOrNormalizeArgumentsA.dhall
@@ -0,0 +1 @@
+True || False || False
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorOrNormalizeArgumentsB.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorOrNormalizeArgumentsB.dhall
new file mode 100644
index 0000000..13b3e87
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorOrNormalizeArgumentsB.dhall
@@ -0,0 +1 @@
+Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorPlusA.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorPlusA.dhall
new file mode 100644
index 0000000..8d2f097
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorPlusA.dhall
@@ -0,0 +1 @@
+1 + 1
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorPlusB.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorPlusB.dhall
new file mode 100644
index 0000000..2f184a4
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorPlusB.dhall
@@ -0,0 +1 @@
+Natural
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorPlusNormalizeArgumentsA.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorPlusNormalizeArgumentsA.dhall
new file mode 100644
index 0000000..07eab75
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorPlusNormalizeArgumentsA.dhall
@@ -0,0 +1 @@
+1 + 1 + (1 + 1)
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorPlusNormalizeArgumentsB.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorPlusNormalizeArgumentsB.dhall
new file mode 100644
index 0000000..2f184a4
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorPlusNormalizeArgumentsB.dhall
@@ -0,0 +1 @@
+Natural
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorTextConcatenateA.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorTextConcatenateA.dhall
new file mode 100644
index 0000000..92c0744
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorTextConcatenateA.dhall
@@ -0,0 +1 @@
+"a" ++ "b"
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorTextConcatenateB.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorTextConcatenateB.dhall
new file mode 100644
index 0000000..3de705a
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorTextConcatenateB.dhall
@@ -0,0 +1 @@
+Text
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorTextConcatenateNormalizeArgumentsA.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorTextConcatenateNormalizeArgumentsA.dhall
new file mode 100644
index 0000000..f97a0a8
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorTextConcatenateNormalizeArgumentsA.dhall
@@ -0,0 +1 @@
+"x" ++ "a" ++ ("y" ++ "b")
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorTextConcatenateNormalizeArgumentsB.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorTextConcatenateNormalizeArgumentsB.dhall
new file mode 100644
index 0000000..3de705a
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorTextConcatenateNormalizeArgumentsB.dhall
@@ -0,0 +1 @@
+Text
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorTimesA.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorTimesA.dhall
new file mode 100644
index 0000000..6f65828
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorTimesA.dhall
@@ -0,0 +1 @@
+1 * 1
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorTimesB.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorTimesB.dhall
new file mode 100644
index 0000000..2f184a4
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorTimesB.dhall
@@ -0,0 +1 @@
+Natural
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorTimesNormalizeArgumentsA.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorTimesNormalizeArgumentsA.dhall
new file mode 100644
index 0000000..a8584f5
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorTimesNormalizeArgumentsA.dhall
@@ -0,0 +1 @@
+1 * 1 * (1 * 1)
diff --git a/dhall-lang/tests/type-inference/success/unit/OperatorTimesNormalizeArgumentsB.dhall b/dhall-lang/tests/type-inference/success/unit/OperatorTimesNormalizeArgumentsB.dhall
new file mode 100644
index 0000000..2f184a4
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OperatorTimesNormalizeArgumentsB.dhall
@@ -0,0 +1 @@
+Natural
diff --git a/dhall-lang/tests/type-inference/success/unit/OptionalA.dhall b/dhall-lang/tests/type-inference/success/unit/OptionalA.dhall
new file mode 100644
index 0000000..f6469f0
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OptionalA.dhall
@@ -0,0 +1 @@
+Optional
diff --git a/dhall-lang/tests/type-inference/success/unit/OptionalB.dhall b/dhall-lang/tests/type-inference/success/unit/OptionalB.dhall
new file mode 100644
index 0000000..95883c7
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OptionalB.dhall
@@ -0,0 +1 @@
+Type → Type
diff --git a/dhall-lang/tests/type-inference/success/unit/OptionalBuildA.dhall b/dhall-lang/tests/type-inference/success/unit/OptionalBuildA.dhall
new file mode 100644
index 0000000..746a80a
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OptionalBuildA.dhall
@@ -0,0 +1 @@
+Optional/build
diff --git a/dhall-lang/tests/type-inference/success/unit/OptionalBuildB.dhall b/dhall-lang/tests/type-inference/success/unit/OptionalBuildB.dhall
new file mode 100644
index 0000000..c3ecea4
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OptionalBuildB.dhall
@@ -0,0 +1,7 @@
+ ∀(a : Type)
+→ ( ∀(optional : Type)
+ → ∀(just : a → optional)
+ → ∀(nothing : optional)
+ → optional
+ )
+→ Optional a
diff --git a/dhall-lang/tests/type-inference/success/unit/OptionalFoldA.dhall b/dhall-lang/tests/type-inference/success/unit/OptionalFoldA.dhall
new file mode 100644
index 0000000..76cb348
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OptionalFoldA.dhall
@@ -0,0 +1 @@
+Optional/fold
diff --git a/dhall-lang/tests/type-inference/success/unit/OptionalFoldB.dhall b/dhall-lang/tests/type-inference/success/unit/OptionalFoldB.dhall
new file mode 100644
index 0000000..b303f50
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/OptionalFoldB.dhall
@@ -0,0 +1,6 @@
+ ∀(a : Type)
+→ Optional a
+→ ∀(optional : Type)
+→ ∀(just : a → optional)
+→ ∀(nothing : optional)
+→ optional
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordEmptyA.dhall b/dhall-lang/tests/type-inference/success/unit/RecordEmptyA.dhall
new file mode 100644
index 0000000..339130f
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordEmptyA.dhall
@@ -0,0 +1 @@
+{=}
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordEmptyB.dhall b/dhall-lang/tests/type-inference/success/unit/RecordEmptyB.dhall
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordEmptyB.dhall
@@ -0,0 +1 @@
+{}
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordNestedKindA.dhall b/dhall-lang/tests/type-inference/success/unit/RecordNestedKindA.dhall
new file mode 100644
index 0000000..5302b44
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordNestedKindA.dhall
@@ -0,0 +1 @@
+{ a = { b = Type } }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordNestedKindB.dhall b/dhall-lang/tests/type-inference/success/unit/RecordNestedKindB.dhall
new file mode 100644
index 0000000..d4bc6ae
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordNestedKindB.dhall
@@ -0,0 +1 @@
+{ a : { b : Kind } }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordNestedKindLikeA.dhall b/dhall-lang/tests/type-inference/success/unit/RecordNestedKindLikeA.dhall
new file mode 100644
index 0000000..04607c4
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordNestedKindLikeA.dhall
@@ -0,0 +1 @@
+{ a = { b = Type → Type } }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordNestedKindLikeB.dhall b/dhall-lang/tests/type-inference/success/unit/RecordNestedKindLikeB.dhall
new file mode 100644
index 0000000..d4bc6ae
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordNestedKindLikeB.dhall
@@ -0,0 +1 @@
+{ a : { b : Kind } }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordNestedTypeA.dhall b/dhall-lang/tests/type-inference/success/unit/RecordNestedTypeA.dhall
new file mode 100644
index 0000000..f42a476
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordNestedTypeA.dhall
@@ -0,0 +1 @@
+{ a = { b = Bool } }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordNestedTypeB.dhall b/dhall-lang/tests/type-inference/success/unit/RecordNestedTypeB.dhall
new file mode 100644
index 0000000..a6809d6
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordNestedTypeB.dhall
@@ -0,0 +1 @@
+{ a : { b : Type } }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordNestedTypeLikeA.dhall b/dhall-lang/tests/type-inference/success/unit/RecordNestedTypeLikeA.dhall
new file mode 100644
index 0000000..3d61a6b
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordNestedTypeLikeA.dhall
@@ -0,0 +1 @@
+{ a = { b = Bool → Bool } }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordNestedTypeLikeB.dhall b/dhall-lang/tests/type-inference/success/unit/RecordNestedTypeLikeB.dhall
new file mode 100644
index 0000000..a6809d6
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordNestedTypeLikeB.dhall
@@ -0,0 +1 @@
+{ a : { b : Type } }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordOneKindA.dhall b/dhall-lang/tests/type-inference/success/unit/RecordOneKindA.dhall
new file mode 100644
index 0000000..dc1548c
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordOneKindA.dhall
@@ -0,0 +1 @@
+{ x = Type }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordOneKindB.dhall b/dhall-lang/tests/type-inference/success/unit/RecordOneKindB.dhall
new file mode 100644
index 0000000..89fd588
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordOneKindB.dhall
@@ -0,0 +1 @@
+{ x : Kind }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordOneTypeA.dhall b/dhall-lang/tests/type-inference/success/unit/RecordOneTypeA.dhall
new file mode 100644
index 0000000..e6eafbe
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordOneTypeA.dhall
@@ -0,0 +1 @@
+{ x = {} }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordOneTypeB.dhall b/dhall-lang/tests/type-inference/success/unit/RecordOneTypeB.dhall
new file mode 100644
index 0000000..9dab3a1
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordOneTypeB.dhall
@@ -0,0 +1 @@
+{ x : Type }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordOneValueA.dhall b/dhall-lang/tests/type-inference/success/unit/RecordOneValueA.dhall
new file mode 100644
index 0000000..a1c0f74
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordOneValueA.dhall
@@ -0,0 +1 @@
+{ x = {=} }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordOneValueB.dhall b/dhall-lang/tests/type-inference/success/unit/RecordOneValueB.dhall
new file mode 100644
index 0000000..505965c
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordOneValueB.dhall
@@ -0,0 +1 @@
+{ x : {} }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordProjectionByTypeA.dhall b/dhall-lang/tests/type-inference/success/unit/RecordProjectionByTypeA.dhall
new file mode 100644
index 0000000..932485d
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordProjectionByTypeA.dhall
@@ -0,0 +1 @@
+let e = { a = 10, b = "Text" } let s = { a : Natural } in e.(s)
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordProjectionByTypeB.dhall b/dhall-lang/tests/type-inference/success/unit/RecordProjectionByTypeB.dhall
new file mode 100644
index 0000000..2e4df82
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordProjectionByTypeB.dhall
@@ -0,0 +1 @@
+{ a : Natural }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordProjectionByTypeEmptyA.dhall b/dhall-lang/tests/type-inference/success/unit/RecordProjectionByTypeEmptyA.dhall
new file mode 100644
index 0000000..840b505
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordProjectionByTypeEmptyA.dhall
@@ -0,0 +1 @@
+let e = { a = 10, b = "Text" } let s = { } in e.(s)
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordProjectionByTypeEmptyB.dhall b/dhall-lang/tests/type-inference/success/unit/RecordProjectionByTypeEmptyB.dhall
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordProjectionByTypeEmptyB.dhall
@@ -0,0 +1 @@
+{}
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordProjectionByTypeJudgmentalEqualityA.dhall b/dhall-lang/tests/type-inference/success/unit/RecordProjectionByTypeJudgmentalEqualityA.dhall
new file mode 100644
index 0000000..c244434
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordProjectionByTypeJudgmentalEqualityA.dhall
@@ -0,0 +1,5 @@
+-- This tests that we prefer the type from the selector over the inferred field
+-- type from the record
+-- ie the result should be `{ a : Natural → Natural }`
+-- not `{ a : ∀(x : Natural) → Natural }`
+let e = { a = λ(x : Natural) → x } let s = { a : Natural → Natural } in e.(s)
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordProjectionByTypeJudgmentalEqualityB.dhall b/dhall-lang/tests/type-inference/success/unit/RecordProjectionByTypeJudgmentalEqualityB.dhall
new file mode 100644
index 0000000..7f65071
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordProjectionByTypeJudgmentalEqualityB.dhall
@@ -0,0 +1 @@
+{ a : Natural → Natural }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordProjectionEmptyA.dhall b/dhall-lang/tests/type-inference/success/unit/RecordProjectionEmptyA.dhall
new file mode 100644
index 0000000..0357971
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordProjectionEmptyA.dhall
@@ -0,0 +1 @@
+{ x = {=} }.{}
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordProjectionEmptyB.dhall b/dhall-lang/tests/type-inference/success/unit/RecordProjectionEmptyB.dhall
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordProjectionEmptyB.dhall
@@ -0,0 +1 @@
+{}
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordProjectionKindA.dhall b/dhall-lang/tests/type-inference/success/unit/RecordProjectionKindA.dhall
new file mode 100644
index 0000000..a05e737
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordProjectionKindA.dhall
@@ -0,0 +1 @@
+{ x = Type, y = Type }.{ x }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordProjectionKindB.dhall b/dhall-lang/tests/type-inference/success/unit/RecordProjectionKindB.dhall
new file mode 100644
index 0000000..89fd588
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordProjectionKindB.dhall
@@ -0,0 +1 @@
+{ x : Kind }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordProjectionTypeA.dhall b/dhall-lang/tests/type-inference/success/unit/RecordProjectionTypeA.dhall
new file mode 100644
index 0000000..d1d1a6e
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordProjectionTypeA.dhall
@@ -0,0 +1 @@
+{ x = Bool, y = Natural }.{ x }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordProjectionTypeB.dhall b/dhall-lang/tests/type-inference/success/unit/RecordProjectionTypeB.dhall
new file mode 100644
index 0000000..9dab3a1
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordProjectionTypeB.dhall
@@ -0,0 +1 @@
+{ x : Type }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordProjectionValueA.dhall b/dhall-lang/tests/type-inference/success/unit/RecordProjectionValueA.dhall
new file mode 100644
index 0000000..ca18a7a
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordProjectionValueA.dhall
@@ -0,0 +1 @@
+{ x = {=}, y = {=} }.{ x }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordProjectionValueB.dhall b/dhall-lang/tests/type-inference/success/unit/RecordProjectionValueB.dhall
new file mode 100644
index 0000000..505965c
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordProjectionValueB.dhall
@@ -0,0 +1 @@
+{ x : {} }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordSelectionKindA.dhall b/dhall-lang/tests/type-inference/success/unit/RecordSelectionKindA.dhall
new file mode 100644
index 0000000..9d7b80b
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordSelectionKindA.dhall
@@ -0,0 +1 @@
+{ x = Type }.x
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordSelectionKindB.dhall b/dhall-lang/tests/type-inference/success/unit/RecordSelectionKindB.dhall
new file mode 100644
index 0000000..894beeb
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordSelectionKindB.dhall
@@ -0,0 +1 @@
+Kind
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordSelectionTypeA.dhall b/dhall-lang/tests/type-inference/success/unit/RecordSelectionTypeA.dhall
new file mode 100644
index 0000000..84e33f3
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordSelectionTypeA.dhall
@@ -0,0 +1 @@
+{ x = {} }.x
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordSelectionTypeB.dhall b/dhall-lang/tests/type-inference/success/unit/RecordSelectionTypeB.dhall
new file mode 100644
index 0000000..245bc9d
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordSelectionTypeB.dhall
@@ -0,0 +1 @@
+Type
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordSelectionValueA.dhall b/dhall-lang/tests/type-inference/success/unit/RecordSelectionValueA.dhall
new file mode 100644
index 0000000..cfac976
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordSelectionValueA.dhall
@@ -0,0 +1 @@
+{ x = {=} }.x
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordSelectionValueB.dhall b/dhall-lang/tests/type-inference/success/unit/RecordSelectionValueB.dhall
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordSelectionValueB.dhall
@@ -0,0 +1 @@
+{}
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordTypeA.dhall b/dhall-lang/tests/type-inference/success/unit/RecordTypeA.dhall
new file mode 100644
index 0000000..bc8d797
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordTypeA.dhall
@@ -0,0 +1 @@
+{ x : Bool }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordTypeB.dhall b/dhall-lang/tests/type-inference/success/unit/RecordTypeB.dhall
new file mode 100644
index 0000000..245bc9d
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordTypeB.dhall
@@ -0,0 +1 @@
+Type
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordTypeEmptyA.dhall b/dhall-lang/tests/type-inference/success/unit/RecordTypeEmptyA.dhall
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordTypeEmptyA.dhall
@@ -0,0 +1 @@
+{}
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordTypeEmptyB.dhall b/dhall-lang/tests/type-inference/success/unit/RecordTypeEmptyB.dhall
new file mode 100644
index 0000000..245bc9d
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordTypeEmptyB.dhall
@@ -0,0 +1 @@
+Type
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordTypeKindA.dhall b/dhall-lang/tests/type-inference/success/unit/RecordTypeKindA.dhall
new file mode 100644
index 0000000..89fd588
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordTypeKindA.dhall
@@ -0,0 +1 @@
+{ x : Kind }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordTypeKindB.dhall b/dhall-lang/tests/type-inference/success/unit/RecordTypeKindB.dhall
new file mode 100644
index 0000000..9b48bbb
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordTypeKindB.dhall
@@ -0,0 +1 @@
+Sort
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordTypeKindLikeA.dhall b/dhall-lang/tests/type-inference/success/unit/RecordTypeKindLikeA.dhall
new file mode 100644
index 0000000..381a8d4
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordTypeKindLikeA.dhall
@@ -0,0 +1 @@
+{ a : Kind → Kind }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordTypeKindLikeB.dhall b/dhall-lang/tests/type-inference/success/unit/RecordTypeKindLikeB.dhall
new file mode 100644
index 0000000..9b48bbb
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordTypeKindLikeB.dhall
@@ -0,0 +1 @@
+Sort
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordTypeNestedKindA.dhall b/dhall-lang/tests/type-inference/success/unit/RecordTypeNestedKindA.dhall
new file mode 100644
index 0000000..d4bc6ae
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordTypeNestedKindA.dhall
@@ -0,0 +1 @@
+{ a : { b : Kind } }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordTypeNestedKindB.dhall b/dhall-lang/tests/type-inference/success/unit/RecordTypeNestedKindB.dhall
new file mode 100644
index 0000000..9b48bbb
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordTypeNestedKindB.dhall
@@ -0,0 +1 @@
+Sort
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordTypeNestedKindLikeA.dhall b/dhall-lang/tests/type-inference/success/unit/RecordTypeNestedKindLikeA.dhall
new file mode 100644
index 0000000..598ffb6
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordTypeNestedKindLikeA.dhall
@@ -0,0 +1 @@
+{ a : { b : Kind → Kind } }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordTypeNestedKindLikeB.dhall b/dhall-lang/tests/type-inference/success/unit/RecordTypeNestedKindLikeB.dhall
new file mode 100644
index 0000000..9b48bbb
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordTypeNestedKindLikeB.dhall
@@ -0,0 +1 @@
+Sort
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordTypeTypeA.dhall b/dhall-lang/tests/type-inference/success/unit/RecordTypeTypeA.dhall
new file mode 100644
index 0000000..9dab3a1
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordTypeTypeA.dhall
@@ -0,0 +1 @@
+{ x : Type }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecordTypeTypeB.dhall b/dhall-lang/tests/type-inference/success/unit/RecordTypeTypeB.dhall
new file mode 100644
index 0000000..894beeb
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecordTypeTypeB.dhall
@@ -0,0 +1 @@
+Kind
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeLhsEmptyA.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeLhsEmptyA.dhall
new file mode 100644
index 0000000..3515f16
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeLhsEmptyA.dhall
@@ -0,0 +1 @@
+{=} ∧ { x = True }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeLhsEmptyB.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeLhsEmptyB.dhall
new file mode 100644
index 0000000..bc8d797
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeLhsEmptyB.dhall
@@ -0,0 +1 @@
+{ x : Bool }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRecursivelyA.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRecursivelyA.dhall
new file mode 100644
index 0000000..808bd2c
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRecursivelyA.dhall
@@ -0,0 +1 @@
+{ x = { a = True } } ∧ { x = { b = True } }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRecursivelyB.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRecursivelyB.dhall
new file mode 100644
index 0000000..22e032c
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRecursivelyB.dhall
@@ -0,0 +1 @@
+{ x : { a : Bool, b : Bool } }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRecursivelyKindsA.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRecursivelyKindsA.dhall
new file mode 100644
index 0000000..aa433f9
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRecursivelyKindsA.dhall
@@ -0,0 +1 @@
+{ x = { a = Type } } ∧ { x = { b = Type } }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRecursivelyKindsB.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRecursivelyKindsB.dhall
new file mode 100644
index 0000000..a039ef5
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRecursivelyKindsB.dhall
@@ -0,0 +1 @@
+{ x : { a : Kind, b : Kind } }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRecursivelyTypesA.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRecursivelyTypesA.dhall
new file mode 100644
index 0000000..4b19411
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRecursivelyTypesA.dhall
@@ -0,0 +1 @@
+{ x = { a = Bool } } ∧ { x = { b = Natural } }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRecursivelyTypesB.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRecursivelyTypesB.dhall
new file mode 100644
index 0000000..e46b614
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRecursivelyTypesB.dhall
@@ -0,0 +1 @@
+{ x : { a : Type, b : Type } }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRhsEmptyA.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRhsEmptyA.dhall
new file mode 100644
index 0000000..b88e720
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRhsEmptyA.dhall
@@ -0,0 +1 @@
+{ x = True } ∧ {=}
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRhsEmptyB.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRhsEmptyB.dhall
new file mode 100644
index 0000000..bc8d797
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeRhsEmptyB.dhall
@@ -0,0 +1 @@
+{ x : Bool }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeTwoA.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeTwoA.dhall
new file mode 100644
index 0000000..84951b0
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeTwoA.dhall
@@ -0,0 +1 @@
+{ x = True } ∧ { y = True }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeTwoB.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeTwoB.dhall
new file mode 100644
index 0000000..bfc2aa5
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeTwoB.dhall
@@ -0,0 +1 @@
+{ x : Bool, y : Bool }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeTwoKindsA.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeTwoKindsA.dhall
new file mode 100644
index 0000000..0416367
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeTwoKindsA.dhall
@@ -0,0 +1 @@
+{ x = Type } ∧ { y = Type }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeTwoKindsB.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeTwoKindsB.dhall
new file mode 100644
index 0000000..2a0a0fc
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeTwoKindsB.dhall
@@ -0,0 +1 @@
+{ x : Kind, y : Kind }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeTwoTypesA.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeTwoTypesA.dhall
new file mode 100644
index 0000000..ca67e6e
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeTwoTypesA.dhall
@@ -0,0 +1 @@
+{ x = Bool } ∧ { y = Natural }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeTwoTypesB.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeTwoTypesB.dhall
new file mode 100644
index 0000000..341a101
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordMergeTwoTypesB.dhall
@@ -0,0 +1 @@
+{ x : Type, y : Type }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRecursivelyA.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRecursivelyA.dhall
new file mode 100644
index 0000000..639e232
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRecursivelyA.dhall
@@ -0,0 +1 @@
+{ x : { a : Bool } } ⩓ { y : { b : Bool } }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRecursivelyB.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRecursivelyB.dhall
new file mode 100644
index 0000000..245bc9d
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRecursivelyB.dhall
@@ -0,0 +1 @@
+Type
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRecursivelyKindsA.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRecursivelyKindsA.dhall
new file mode 100644
index 0000000..e0fba76
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRecursivelyKindsA.dhall
@@ -0,0 +1 @@
+{ x : { a : Kind } } ⩓ { y : { b : Kind } }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRecursivelyKindsB.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRecursivelyKindsB.dhall
new file mode 100644
index 0000000..9b48bbb
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRecursivelyKindsB.dhall
@@ -0,0 +1 @@
+Sort
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRecursivelyTypesA.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRecursivelyTypesA.dhall
new file mode 100644
index 0000000..476b609
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRecursivelyTypesA.dhall
@@ -0,0 +1 @@
+{ x : { a : Type } } ⩓ { y : { b : Type } }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRecursivelyTypesB.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRecursivelyTypesB.dhall
new file mode 100644
index 0000000..894beeb
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRecursivelyTypesB.dhall
@@ -0,0 +1 @@
+Kind
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRhsEmptyA.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRhsEmptyA.dhall
new file mode 100644
index 0000000..c3ef398
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRhsEmptyA.dhall
@@ -0,0 +1 @@
+{ x : Bool } ⩓ {}
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRhsEmptyB.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRhsEmptyB.dhall
new file mode 100644
index 0000000..245bc9d
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeRhsEmptyB.dhall
@@ -0,0 +1 @@
+Type
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeTwoA.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeTwoA.dhall
new file mode 100644
index 0000000..84caa9c
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeTwoA.dhall
@@ -0,0 +1 @@
+{ x : Bool } ⩓ { y : Bool }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeTwoB.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeTwoB.dhall
new file mode 100644
index 0000000..245bc9d
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeTwoB.dhall
@@ -0,0 +1 @@
+Type
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeTwoKindsA.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeTwoKindsA.dhall
new file mode 100644
index 0000000..e16f9bd
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeTwoKindsA.dhall
@@ -0,0 +1 @@
+{ x : Kind } ⩓ { y : Kind }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeTwoKindsB.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeTwoKindsB.dhall
new file mode 100644
index 0000000..9b48bbb
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeTwoKindsB.dhall
@@ -0,0 +1 @@
+Sort
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeTwoTypesA.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeTwoTypesA.dhall
new file mode 100644
index 0000000..a47ce71
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeTwoTypesA.dhall
@@ -0,0 +1 @@
+{ x : Type } ⩓ { y : Type }
diff --git a/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeTwoTypesB.dhall b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeTwoTypesB.dhall
new file mode 100644
index 0000000..894beeb
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RecursiveRecordTypeMergeTwoTypesB.dhall
@@ -0,0 +1 @@
+Kind
diff --git a/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeRhsEmptyA.dhall b/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeRhsEmptyA.dhall
new file mode 100644
index 0000000..c7f39f9
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeRhsEmptyA.dhall
@@ -0,0 +1 @@
+{ x = {=} } ⫽ {=}
diff --git a/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeRhsEmptyB.dhall b/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeRhsEmptyB.dhall
new file mode 100644
index 0000000..505965c
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeRhsEmptyB.dhall
@@ -0,0 +1 @@
+{ x : {} }
diff --git a/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoA.dhall b/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoA.dhall
new file mode 100644
index 0000000..dd47d94
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoA.dhall
@@ -0,0 +1 @@
+{ x = {=} } ⫽ { x = {=} }
diff --git a/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoB.dhall b/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoB.dhall
new file mode 100644
index 0000000..505965c
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoB.dhall
@@ -0,0 +1 @@
+{ x : {} }
diff --git a/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoDifferentA.dhall b/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoDifferentA.dhall
new file mode 100644
index 0000000..2a8afdb
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoDifferentA.dhall
@@ -0,0 +1 @@
+{ x = {=} } ⫽ { x = True }
diff --git a/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoDifferentB.dhall b/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoDifferentB.dhall
new file mode 100644
index 0000000..bc8d797
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoDifferentB.dhall
@@ -0,0 +1 @@
+{ x : Bool }
diff --git a/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoKindsA.dhall b/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoKindsA.dhall
new file mode 100644
index 0000000..a7761d0
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoKindsA.dhall
@@ -0,0 +1 @@
+{ x = Type } ⫽ { x = Type }
diff --git a/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoKindsB.dhall b/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoKindsB.dhall
new file mode 100644
index 0000000..89fd588
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoKindsB.dhall
@@ -0,0 +1 @@
+{ x : Kind }
diff --git a/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoTypesA.dhall b/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoTypesA.dhall
new file mode 100644
index 0000000..b9ab433
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoTypesA.dhall
@@ -0,0 +1 @@
+{ x = Bool } ⫽ { x = Natural }
diff --git a/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoTypesB.dhall b/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoTypesB.dhall
new file mode 100644
index 0000000..9dab3a1
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/RightBiasedRecordMergeTwoTypesB.dhall
@@ -0,0 +1 @@
+{ x : Type }
diff --git a/dhall-lang/tests/type-inference/success/unit/SomeTrueA.dhall b/dhall-lang/tests/type-inference/success/unit/SomeTrueA.dhall
new file mode 100644
index 0000000..d99c1ad
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/SomeTrueA.dhall
@@ -0,0 +1 @@
+Some True
diff --git a/dhall-lang/tests/type-inference/success/unit/SomeTrueB.dhall b/dhall-lang/tests/type-inference/success/unit/SomeTrueB.dhall
new file mode 100644
index 0000000..c084db6
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/SomeTrueB.dhall
@@ -0,0 +1 @@
+Optional Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/TextA.dhall b/dhall-lang/tests/type-inference/success/unit/TextA.dhall
new file mode 100644
index 0000000..3de705a
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/TextA.dhall
@@ -0,0 +1 @@
+Text
diff --git a/dhall-lang/tests/type-inference/success/unit/TextB.dhall b/dhall-lang/tests/type-inference/success/unit/TextB.dhall
new file mode 100644
index 0000000..245bc9d
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/TextB.dhall
@@ -0,0 +1 @@
+Type
diff --git a/dhall-lang/tests/type-inference/success/unit/TextLiteralA.dhall b/dhall-lang/tests/type-inference/success/unit/TextLiteralA.dhall
new file mode 100644
index 0000000..231f150
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/TextLiteralA.dhall
@@ -0,0 +1 @@
+"a"
diff --git a/dhall-lang/tests/type-inference/success/unit/TextLiteralB.dhall b/dhall-lang/tests/type-inference/success/unit/TextLiteralB.dhall
new file mode 100644
index 0000000..3de705a
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/TextLiteralB.dhall
@@ -0,0 +1 @@
+Text
diff --git a/dhall-lang/tests/type-inference/success/unit/TextLiteralNormalizeArgumentsA.dhall b/dhall-lang/tests/type-inference/success/unit/TextLiteralNormalizeArgumentsA.dhall
new file mode 100644
index 0000000..5fe19d1
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/TextLiteralNormalizeArgumentsA.dhall
@@ -0,0 +1 @@
+"a${if True then "a" else "b"}"
diff --git a/dhall-lang/tests/type-inference/success/unit/TextLiteralNormalizeArgumentsB.dhall b/dhall-lang/tests/type-inference/success/unit/TextLiteralNormalizeArgumentsB.dhall
new file mode 100644
index 0000000..3de705a
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/TextLiteralNormalizeArgumentsB.dhall
@@ -0,0 +1 @@
+Text
diff --git a/dhall-lang/tests/type-inference/success/unit/TextLiteralWithInterpolationA.dhall b/dhall-lang/tests/type-inference/success/unit/TextLiteralWithInterpolationA.dhall
new file mode 100644
index 0000000..b445058
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/TextLiteralWithInterpolationA.dhall
@@ -0,0 +1 @@
+"a${"b"}"
diff --git a/dhall-lang/tests/type-inference/success/unit/TextLiteralWithInterpolationB.dhall b/dhall-lang/tests/type-inference/success/unit/TextLiteralWithInterpolationB.dhall
new file mode 100644
index 0000000..3de705a
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/TextLiteralWithInterpolationB.dhall
@@ -0,0 +1 @@
+Text
diff --git a/dhall-lang/tests/type-inference/success/unit/TextShowA.dhall b/dhall-lang/tests/type-inference/success/unit/TextShowA.dhall
new file mode 100644
index 0000000..aff32cd
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/TextShowA.dhall
@@ -0,0 +1 @@
+Text/show
diff --git a/dhall-lang/tests/type-inference/success/unit/TextShowB.dhall b/dhall-lang/tests/type-inference/success/unit/TextShowB.dhall
new file mode 100644
index 0000000..73a7ee3
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/TextShowB.dhall
@@ -0,0 +1 @@
+Text → Text
diff --git a/dhall-lang/tests/type-inference/success/unit/ToMapA.dhall b/dhall-lang/tests/type-inference/success/unit/ToMapA.dhall
new file mode 100644
index 0000000..5353bf3
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/ToMapA.dhall
@@ -0,0 +1 @@
+toMap { foo= 1, bar= 4, baz= 9 }
diff --git a/dhall-lang/tests/type-inference/success/unit/ToMapB.dhall b/dhall-lang/tests/type-inference/success/unit/ToMapB.dhall
new file mode 100644
index 0000000..4a9542d
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/ToMapB.dhall
@@ -0,0 +1 @@
+List { mapKey : Text, mapValue : Natural }
diff --git a/dhall-lang/tests/type-inference/success/unit/TrueA.dhall b/dhall-lang/tests/type-inference/success/unit/TrueA.dhall
new file mode 100644
index 0000000..0ca9514
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/TrueA.dhall
@@ -0,0 +1 @@
+True
diff --git a/dhall-lang/tests/type-inference/success/unit/TrueB.dhall b/dhall-lang/tests/type-inference/success/unit/TrueB.dhall
new file mode 100644
index 0000000..13b3e87
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/TrueB.dhall
@@ -0,0 +1 @@
+Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/TypeA.dhall b/dhall-lang/tests/type-inference/success/unit/TypeA.dhall
new file mode 100644
index 0000000..245bc9d
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/TypeA.dhall
@@ -0,0 +1 @@
+Type
diff --git a/dhall-lang/tests/type-inference/success/unit/TypeAnnotationA.dhall b/dhall-lang/tests/type-inference/success/unit/TypeAnnotationA.dhall
new file mode 100644
index 0000000..57f367a
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/TypeAnnotationA.dhall
@@ -0,0 +1 @@
+True : Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/TypeAnnotationB.dhall b/dhall-lang/tests/type-inference/success/unit/TypeAnnotationB.dhall
new file mode 100644
index 0000000..13b3e87
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/TypeAnnotationB.dhall
@@ -0,0 +1 @@
+Bool
diff --git a/dhall-lang/tests/type-inference/success/unit/TypeAnnotationSortA.dhall b/dhall-lang/tests/type-inference/success/unit/TypeAnnotationSortA.dhall
new file mode 100644
index 0000000..3b871cd
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/TypeAnnotationSortA.dhall
@@ -0,0 +1 @@
+Kind : Sort
diff --git a/dhall-lang/tests/type-inference/success/unit/TypeAnnotationSortB.dhall b/dhall-lang/tests/type-inference/success/unit/TypeAnnotationSortB.dhall
new file mode 100644
index 0000000..9b48bbb
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/TypeAnnotationSortB.dhall
@@ -0,0 +1 @@
+Sort
diff --git a/dhall-lang/tests/type-inference/success/unit/TypeB.dhall b/dhall-lang/tests/type-inference/success/unit/TypeB.dhall
new file mode 100644
index 0000000..894beeb
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/TypeB.dhall
@@ -0,0 +1 @@
+Kind
diff --git a/dhall-lang/tests/type-inference/success/unit/UnionConstructorEmptyFieldA.dhall b/dhall-lang/tests/type-inference/success/unit/UnionConstructorEmptyFieldA.dhall
new file mode 100644
index 0000000..55ab179
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/UnionConstructorEmptyFieldA.dhall
@@ -0,0 +1 @@
+< x | y : Bool >.x
diff --git a/dhall-lang/tests/type-inference/success/unit/UnionConstructorEmptyFieldB.dhall b/dhall-lang/tests/type-inference/success/unit/UnionConstructorEmptyFieldB.dhall
new file mode 100644
index 0000000..48f3e98
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/UnionConstructorEmptyFieldB.dhall
@@ -0,0 +1 @@
+< x | y : Bool >
diff --git a/dhall-lang/tests/type-inference/success/unit/UnionConstructorFieldA.dhall b/dhall-lang/tests/type-inference/success/unit/UnionConstructorFieldA.dhall
new file mode 100644
index 0000000..facb188
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/UnionConstructorFieldA.dhall
@@ -0,0 +1 @@
+< x : Bool >.x
diff --git a/dhall-lang/tests/type-inference/success/unit/UnionConstructorFieldB.dhall b/dhall-lang/tests/type-inference/success/unit/UnionConstructorFieldB.dhall
new file mode 100644
index 0000000..a8f997f
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/UnionConstructorFieldB.dhall
@@ -0,0 +1 @@
+∀(x : Bool) → < x : Bool >
diff --git a/dhall-lang/tests/type-inference/success/unit/UnionLiteralOneA.dhall b/dhall-lang/tests/type-inference/success/unit/UnionLiteralOneA.dhall
new file mode 100644
index 0000000..0b7984f
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/UnionLiteralOneA.dhall
@@ -0,0 +1 @@
+< x = True >
diff --git a/dhall-lang/tests/type-inference/success/unit/UnionLiteralOneB.dhall b/dhall-lang/tests/type-inference/success/unit/UnionLiteralOneB.dhall
new file mode 100644
index 0000000..94c2ce1
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/UnionLiteralOneB.dhall
@@ -0,0 +1 @@
+< x : Bool >
diff --git a/dhall-lang/tests/type-inference/success/unit/UnionTypeEmptyA.dhall b/dhall-lang/tests/type-inference/success/unit/UnionTypeEmptyA.dhall
new file mode 100644
index 0000000..b554d9e
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/UnionTypeEmptyA.dhall
@@ -0,0 +1 @@
+<>
diff --git a/dhall-lang/tests/type-inference/success/unit/UnionTypeEmptyB.dhall b/dhall-lang/tests/type-inference/success/unit/UnionTypeEmptyB.dhall
new file mode 100644
index 0000000..245bc9d
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/UnionTypeEmptyB.dhall
@@ -0,0 +1 @@
+Type
diff --git a/dhall-lang/tests/type-inference/success/unit/UnionTypeKindA.dhall b/dhall-lang/tests/type-inference/success/unit/UnionTypeKindA.dhall
new file mode 100644
index 0000000..e89036d
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/UnionTypeKindA.dhall
@@ -0,0 +1 @@
+< x : Kind >
diff --git a/dhall-lang/tests/type-inference/success/unit/UnionTypeKindB.dhall b/dhall-lang/tests/type-inference/success/unit/UnionTypeKindB.dhall
new file mode 100644
index 0000000..9b48bbb
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/UnionTypeKindB.dhall
@@ -0,0 +1 @@
+Sort
diff --git a/dhall-lang/tests/type-inference/success/unit/UnionTypeOneA.dhall b/dhall-lang/tests/type-inference/success/unit/UnionTypeOneA.dhall
new file mode 100644
index 0000000..94c2ce1
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/UnionTypeOneA.dhall
@@ -0,0 +1 @@
+< x : Bool >
diff --git a/dhall-lang/tests/type-inference/success/unit/UnionTypeOneB.dhall b/dhall-lang/tests/type-inference/success/unit/UnionTypeOneB.dhall
new file mode 100644
index 0000000..245bc9d
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/UnionTypeOneB.dhall
@@ -0,0 +1 @@
+Type
diff --git a/dhall-lang/tests/type-inference/success/unit/UnionTypeTypeA.dhall b/dhall-lang/tests/type-inference/success/unit/UnionTypeTypeA.dhall
new file mode 100644
index 0000000..6e17707
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/UnionTypeTypeA.dhall
@@ -0,0 +1 @@
+< x : Type >
diff --git a/dhall-lang/tests/type-inference/success/unit/UnionTypeTypeB.dhall b/dhall-lang/tests/type-inference/success/unit/UnionTypeTypeB.dhall
new file mode 100644
index 0000000..894beeb
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/UnionTypeTypeB.dhall
@@ -0,0 +1 @@
+Kind
diff --git a/dhall-lang/tests/typecheck/failure/customHeadersUsingBoundVariable.dhall b/dhall-lang/tests/typecheck/failure/customHeadersUsingBoundVariable.dhall
index b3c6893..afa3b5a 100644
--- a/dhall-lang/tests/typecheck/failure/customHeadersUsingBoundVariable.dhall
+++ b/dhall-lang/tests/typecheck/failure/customHeadersUsingBoundVariable.dhall
@@ -11,5 +11,5 @@
let x = "Bar"
in https://httpbin.org/headers
- using [ { header = "Foo", value = x } ]
+ using [ { mapKey = "Foo", mapValue = x } ]
as Text
diff --git a/dhall.cabal b/dhall.cabal
index fde619d..8bc40cd 100644
--- a/dhall.cabal
+++ b/dhall.cabal
@@ -1,5 +1,5 @@
Name: dhall
-Version: 1.24.0
+Version: 1.25.0
Cabal-Version: >=1.10
Build-Type: Simple
Tested-With: GHC == 7.10.3, GHC == 8.4.3, GHC == 8.6.1
@@ -102,8 +102,10 @@ Extra-Source-Files:
dhall-lang/Prelude/Text/concatSep
dhall-lang/Prelude/Text/package.dhall
dhall-lang/Prelude/Text/show
+ dhall-lang/tests/binary-decode/failure/unit/*.dhallb
dhall-lang/tests/binary-decode/success/unit/*.dhall
dhall-lang/tests/binary-decode/success/unit/*.dhallb
+ dhall-lang/tests/import/cache/dhall/1220efc43103e49b56c5bf089db8e0365bbfc455b8a2f0dc6ee5727a3586f85969fd
dhall-lang/tests/import/data/*.txt
dhall-lang/tests/import/data/*.dhall
dhall-lang/tests/import/data/fieldOrder/*.dhall
@@ -243,8 +245,142 @@ Extra-Source-Files:
dhall-lang/tests/parser/success/unit/*.dhallb
dhall-lang/tests/parser/success/unit/import/*.dhall
dhall-lang/tests/parser/success/unit/import/*.dhallb
+ dhall-lang/tests/parser/success/unit/import/urls/*.dhall
+ dhall-lang/tests/parser/success/unit/import/urls/*.dhallb
dhall-lang/tests/parser/success/text/*.dhall
dhall-lang/tests/parser/success/text/*.dhallb
+ dhall-lang/tests/semantic-hash/success/*.dhall
+ dhall-lang/tests/semantic-hash/success/*.hash
+ dhall-lang/tests/semantic-hash/success/haskell-tutorial/access/*.dhall
+ dhall-lang/tests/semantic-hash/success/haskell-tutorial/access/*.hash
+ dhall-lang/tests/semantic-hash/success/haskell-tutorial/combineTypes/*.dhall
+ dhall-lang/tests/semantic-hash/success/haskell-tutorial/combineTypes/*.hash
+ dhall-lang/tests/semantic-hash/success/haskell-tutorial/prefer/*.dhall
+ dhall-lang/tests/semantic-hash/success/haskell-tutorial/prefer/*.hash
+ dhall-lang/tests/semantic-hash/success/haskell-tutorial/projection/*.dhall
+ dhall-lang/tests/semantic-hash/success/haskell-tutorial/projection/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Bool/and/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Bool/and/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Bool/build/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Bool/build/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Bool/even/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Bool/even/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Bool/fold/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Bool/fold/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Bool/not/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Bool/not/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Bool/or/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Bool/or/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Bool/show/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Bool/show/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Double/show/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Double/show/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Integer/show/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Integer/show/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Integer/toDouble/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Integer/toDouble/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/List/all/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/List/all/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/List/any/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/List/any/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/List/build/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/List/build/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/List/concat/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/List/concat/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/List/concatMap/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/List/concatMap/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/List/filter/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/List/filter/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/List/fold/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/List/fold/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/List/generate/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/List/generate/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/List/head/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/List/head/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/List/indexed/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/List/indexed/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/List/iterate/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/List/iterate/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/List/last/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/List/last/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/List/length/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/List/length/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/List/map/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/List/map/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/List/null/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/List/null/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/List/replicate/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/List/replicate/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/List/reverse/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/List/reverse/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/List/shifted/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/List/shifted/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/List/unzip/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/List/unzip/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Natural/build/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Natural/build/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Natural/enumerate/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Natural/enumerate/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Natural/even/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Natural/even/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Natural/isZero/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Natural/isZero/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Natural/odd/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Natural/odd/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Natural/product/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Natural/product/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Natural/show/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Natural/show/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Natural/sum/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Natural/sum/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Natural/toDouble/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Natural/toDouble/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Natural/toInteger/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Natural/toInteger/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Optional/all/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Optional/all/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Optional/any/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Optional/any/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Optional/build/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Optional/build/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Optional/filter/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Optional/filter/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Optional/fold/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Optional/fold/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Optional/head/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Optional/head/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Optional/last/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Optional/last/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Optional/length/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Optional/length/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Optional/map/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Optional/map/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Optional/null/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Optional/null/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Optional/toList/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Optional/toList/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Optional/unzip/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Optional/unzip/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Text/concat/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Text/concat/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Text/concatMap/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Text/concatMap/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Text/concatMapSep/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Text/concatMapSep/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Text/concatSep/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Text/concatSep/*.hash
+ dhall-lang/tests/semantic-hash/success/prelude/Text/show/*.dhall
+ dhall-lang/tests/semantic-hash/success/prelude/Text/show/*.hash
+ dhall-lang/tests/semantic-hash/success/simple/*.dhall
+ dhall-lang/tests/semantic-hash/success/simple/*.hash
+ dhall-lang/tests/semantic-hash/success/simplifications/*.dhall
+ dhall-lang/tests/semantic-hash/success/simplifications/*.hash
dhall-lang/tests/typecheck/data/*.dhall
dhall-lang/tests/typecheck/failure/*.dhall
dhall-lang/tests/typecheck/success/*.dhall
@@ -367,8 +503,12 @@ Extra-Source-Files:
dhall-lang/tests/typecheck/success/prelude/Text/concatSep/*.dhall
dhall-lang/tests/typecheck/success/simple/access/*.dhall
dhall-lang/tests/typecheck/success/simple/*.dhall
+ dhall-lang/tests/type-inference/success/simple/*.dhall
+ dhall-lang/tests/type-inference/success/unit/*.dhall
tests/format/*.dhall
tests/lint/success/*.dhall
+ tests/diff/*.dhall
+ tests/diff/*.txt
tests/regression/*.dhall
tests/tutorial/*.dhall
@@ -400,17 +540,19 @@ Library
containers >= 0.5.0.0 && < 0.7 ,
contravariant < 1.6 ,
cryptonite >= 0.23 && < 1.0 ,
+ deepseq < 1.5 ,
Diff >= 0.2 && < 0.4 ,
directory >= 1.2.2.0 && < 1.4 ,
dotgen >= 0.4.2 && < 0.5 ,
+ either,
exceptions >= 0.8.3 && < 0.11,
filepath >= 1.4 && < 1.5 ,
haskeline >= 0.7.2.1 && < 0.8 ,
- lens-family-core >= 1.0.0 && < 1.3 ,
+ lens-family-core >= 1.0.0 && < 2.1 ,
megaparsec >= 6.5.0 && < 7.1 ,
memory >= 0.14 && < 0.15,
mtl >= 2.2.1 && < 2.3 ,
- optparse-applicative >= 0.14.0.0 && < 0.15,
+ optparse-applicative >= 0.14.0.0 && < 0.16,
parsers >= 0.12.4 && < 0.13,
prettyprinter >= 1.2.0.1 && < 1.3 ,
prettyprinter-ansi-terminal >= 1.1.1 && < 1.2 ,
@@ -420,6 +562,7 @@ Library
scientific >= 0.3.0.0 && < 0.4 ,
template-haskell < 2.15,
text >= 0.11.1.0 && < 1.3 ,
+ th-lift-instances >= 0.1.13 && < 0.2 ,
transformers >= 0.2.0.0 && < 0.6 ,
transformers-compat >= 0.6.2 && < 0.7 ,
unordered-containers >= 0.1.3.0 && < 0.3 ,
@@ -482,6 +625,8 @@ Library
Dhall.Set,
Dhall.Src,
Dhall.Parser,
+ Dhall.Parser.Expression,
+ Dhall.Parser.Token,
Dhall.Pretty,
Dhall.Repl,
Dhall.Tutorial,
@@ -491,12 +636,11 @@ Library
Dhall.TH
Other-Modules:
Dhall.Pretty.Internal,
- Dhall.Parser.Expression,
Dhall.Parser.Combinators,
- Dhall.Parser.Token,
Dhall.Import.Types,
Dhall.Eval,
Dhall.Util,
+ Dhall.X
Paths_dhall
if flag(with-http)
Other-Modules:
@@ -519,6 +663,7 @@ Test-Suite tasty
GHC-Options: -Wall
Other-Modules:
Dhall.Test.Dhall
+ Dhall.Test.Diff
Dhall.Test.Format
Dhall.Test.Import
Dhall.Test.Lint
@@ -526,8 +671,10 @@ Test-Suite tasty
Dhall.Test.Parser
Dhall.Test.QuickCheck
Dhall.Test.Regression
+ Dhall.Test.SemanticHash
Dhall.Test.Tutorial
Dhall.Test.TypeCheck
+ Dhall.Test.TypeInference
Dhall.Test.Util
Build-Depends:
base >= 4 && < 5 ,
@@ -539,11 +686,14 @@ Test-Suite tasty
directory ,
filepath ,
foldl < 1.5 ,
+ lens-family-core >= 1.0.0 && < 2.1 ,
megaparsec ,
prettyprinter ,
QuickCheck >= 2.10 && < 2.14,
quickcheck-instances >= 0.3.12 && < 0.4 ,
+ semigroups ,
serialise ,
+ spoon < 0.4 ,
tasty >= 0.11.2 && < 1.3 ,
tasty-hunit >= 0.9.2 && < 0.11,
tasty-quickcheck >= 0.9.2 && < 0.11,
@@ -551,6 +701,9 @@ Test-Suite tasty
transformers ,
turtle < 1.6 ,
vector >= 0.11.0.0 && < 0.13
+ if flag(with-http)
+ CPP-Options:
+ -DWITH_HTTP
Default-Language: Haskell2010
Test-Suite doctest
@@ -579,9 +732,9 @@ Benchmark dhall-parser
base >= 4 && < 5 ,
bytestring ,
containers >= 0.5.0.0 && < 0.7,
- criterion >= 1.1 && < 1.6,
dhall ,
directory ,
+ gauge >= 0.2.3 && < 0.3,
serialise ,
text >= 0.11.1.0 && < 1.3
Default-Language: Haskell2010
@@ -596,27 +749,6 @@ Benchmark deep-nested-large-record
Build-Depends:
base >= 4 && < 5 ,
containers >= 0.5.0.0 && < 0.7,
- criterion >= 1.1 && < 1.6,
- dhall
- Default-Language: Haskell2010
-
-Benchmark dhall-command
- Type: exitcode-stdio-1.0
- Main-Is: Main.hs
- Hs-Source-Dirs: benchmark/dhall-command
- Build-Depends:
- base >= 4 && < 5 ,
- dhall
- Default-Language: Haskell2010
- ghc-options: -rtsopts -O2
-
-Benchmark map-operations
- Type: exitcode-stdio-1.0
- Main-Is: Main.hs
- Hs-Source-Dirs: benchmark/map
- Build-Depends:
- base >= 4 && < 5 ,
- criterion >= 1.1 && < 1.6,
- dhall
+ dhall ,
+ gauge >= 0.2.3 && < 0.3
Default-Language: Haskell2010
- ghc-options: -rtsopts -O2
diff --git a/src/Dhall.hs b/src/Dhall.hs
index 120d05e..a01a90b 100644
--- a/src/Dhall.hs
+++ b/src/Dhall.hs
@@ -39,12 +39,19 @@ module Dhall
, detailed
-- * Types
- , Type(..)
+ , Type (..)
, RecordType(..)
, UnionType(..)
, InputType(..)
, Interpret(..)
, InvalidType(..)
+ , ExtractErrors(..)
+ , Extractor
+ , MonadicExtractor
+ , typeError
+ , extractError
+ , toMonadic
+ , fromMonadic
, auto
, genericAuto
, InterpretOptions(..)
@@ -96,15 +103,18 @@ module Dhall
, Generic
) where
-import Control.Applicative (empty, liftA2, (<|>), Alternative)
+import Control.Applicative (empty, liftA2, Alternative)
import Control.Exception (Exception)
import Control.Monad.Trans.State.Strict
import Control.Monad (guard)
import Data.Coerce (coerce)
+import Data.Either.Validation (Validation(..), ealt, eitherToValidation, validationToEither)
import Data.Functor.Contravariant (Contravariant(..), (>$<), Op(..))
import Data.Functor.Contravariant.Divisible (Divisible(..), divided)
+import Data.List.NonEmpty (NonEmpty (..))
import Data.Monoid ((<>))
import Data.Scientific (Scientific)
+import Data.Semigroup (Semigroup)
import Data.Sequence (Seq)
import Data.Text (Text)
import Data.Text.Prettyprint.Doc (Pretty)
@@ -128,6 +138,8 @@ 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.Maybe
+import qualified Data.List.NonEmpty
import qualified Data.Semigroup
import qualified Data.Scientific
import qualified Data.Sequence
@@ -150,19 +162,76 @@ import qualified Dhall.Util
-- >>> :set -XOverloadedStrings
-- >>> :set -XRecordWildCards
+type Extractor s a = Validation (ExtractErrors s a)
+type MonadicExtractor s a = Either (ExtractErrors s a)
+
+
+typeError :: Expr s a -> Expr s a -> Extractor s a b
+typeError expected actual = Failure . ExtractErrors . pure . TypeMismatch $ InvalidType expected actual
+
+extractError :: Text -> Extractor s a b
+extractError = Failure . ExtractErrors . pure . ExtractError
+
+-- | Switches from an @Applicative@ extraction result, able to accumulate errors,
+-- to a @Monad@ extraction result, able to chain sequential operations
+toMonadic :: Extractor s a b -> MonadicExtractor s a b
+toMonadic = validationToEither
+
+-- | Switches from a @Monad@ extraction result, able to chain sequential errors,
+-- to an @Applicative@ extraction result, able to accumulate errors
+fromMonadic :: MonadicExtractor s a b -> Extractor s a b
+fromMonadic = eitherToValidation
+
+newtype ExtractErrors s a = ExtractErrors
+ { getErrors :: NonEmpty (ExtractError s a)
+ } deriving Semigroup
+
+instance (Pretty s, Pretty a, Typeable s, Typeable a) => Show (ExtractErrors s a) where
+ show (ExtractErrors (e :| [])) = show e
+ show (ExtractErrors es) = prefix <> (unlines . Data.List.NonEmpty.toList . fmap show $ es)
+ where
+ prefix =
+ "Multiple errors were encountered during extraction: \n\
+ \ \n"
+
+instance (Pretty s, Pretty a, Typeable s, Typeable a) => Exception (ExtractErrors s a)
+
+{-| Extraction of a value can fail for two reasons, either a type mismatch (which should not happen,
+ as expressions are type-checked against the expected type before being passed to @extract@), or
+ a term-level error, described with a freeform text value.
+-}
+data ExtractError s a =
+ TypeMismatch (InvalidType s a)
+ | ExtractError Text
+
+instance (Pretty s, Pretty a, Typeable s, Typeable a) => Show (ExtractError s a) where
+ show (TypeMismatch e) = show e
+ show (ExtractError es) =
+ _ERROR <> ": Failed extraction \n\
+ \ \n\
+ \The expression type-checked successfully but the transformation to the target \n\
+ \type failed with the following error: \n\
+ \ \n\
+ \" <> Data.Text.unpack es <> "\n\
+ \ \n"
+
+instance (Pretty s, Pretty a, Typeable s, Typeable a) => Exception (ExtractError s a)
+
{-| Every `Type` must obey the contract that if an expression's type matches the
- the `expected` type then the `extract` function must succeed. If not, then
- this exception is thrown
+ the `expected` type then the `extract` function must not fail with a type error.
+ If not, then this value is returned.
- This exception indicates that an invalid `Type` was provided to the `input`
+ This value indicates that an invalid `Type` was provided to the `input`
function
-}
data InvalidType s a = InvalidType
- { invalidTypeExpected :: Expr s a
+ { invalidTypeExpected :: Expr s a
, invalidTypeExpression :: Expr s a
}
deriving (Typeable)
+instance (Pretty s, Typeable s, Pretty a, Typeable a) => Exception (InvalidType s a)
+
_ERROR :: String
_ERROR = "\ESC[1;31mError\ESC[0m"
@@ -185,9 +254,6 @@ instance (Pretty s, Pretty a, Typeable s, Typeable a) => Show (InvalidType s a)
txt0 = Dhall.Util.insert invalidTypeExpected
txt1 = Dhall.Util.insert invalidTypeExpression
-
-instance (Pretty s, Pretty a, Typeable s, Typeable a) => Exception (InvalidType s a)
-
-- | @since 1.16
data InputSettings = InputSettings
{ _rootDirectory :: FilePath
@@ -362,9 +428,8 @@ inputWithSettings settings (Type {..}) txt = do
let normExpr = Dhall.Core.normalizeWith (view normalizer settings) expr'
case extract normExpr of
- Just x -> return x
- Nothing -> Control.Exception.throwIO
- (InvalidType expected expr')
+ Success x -> return x
+ Failure e -> Control.Exception.throwIO e
{-| Type-check and evaluate a Dhall program that is read from the
file-system.
@@ -465,8 +530,8 @@ rawInput
-- ^ The decoded value in Haskell
rawInput (Type {..}) expr = do
case extract (Dhall.Core.normalize expr) of
- Just x -> pure x
- Nothing -> empty
+ Success x -> pure x
+ Failure _e -> empty
{-| Use this to provide more detailed error messages
@@ -601,7 +666,7 @@ detailed =
> input :: Type a -> Text -> IO a
-}
data Type a = Type
- { extract :: Expr Src X -> Maybe a
+ { extract :: Expr Src X -> Extractor Src X a
-- ^ Extracts Haskell value from the Dhall expression
, expected :: Expr Src X
-- ^ Dhall type of the Haskell value
@@ -617,7 +682,7 @@ bool :: Type Bool
bool = Type {..}
where
extract (BoolLit b) = pure b
- extract _ = Nothing
+ extract expr = typeError expected expr
expected = Bool
@@ -630,7 +695,7 @@ natural :: Type Natural
natural = Type {..}
where
extract (NaturalLit n) = pure n
- extract _ = empty
+ extract expr = typeError Natural expr
expected = Natural
@@ -643,7 +708,7 @@ integer :: Type Integer
integer = Type {..}
where
extract (IntegerLit n) = pure n
- extract _ = empty
+ extract expr = typeError Integer expr
expected = Integer
@@ -664,7 +729,7 @@ double :: Type Double
double = Type {..}
where
extract (DoubleLit n) = pure n
- extract _ = empty
+ extract expr = typeError Double expr
expected = Double
@@ -677,7 +742,7 @@ lazyText :: Type Data.Text.Lazy.Text
lazyText = Type {..}
where
extract (TextLit (Chunks [] t)) = pure (Data.Text.Lazy.fromStrict t)
- extract _ = empty
+ extract expr = typeError Text expr
expected = Text
@@ -698,8 +763,8 @@ maybe :: Type a -> Type (Maybe a)
maybe (Type extractIn expectedIn) = Type extractOut expectedOut
where
extractOut (Some e ) = fmap Just (extractIn e)
- extractOut (App None _) = return Nothing
- extractOut _ = empty
+ extractOut (App None _) = pure Nothing
+ extractOut expr = typeError expectedOut expr
expectedOut = App Optional expectedIn
@@ -712,7 +777,7 @@ sequence :: Type a -> Type (Seq a)
sequence (Type extractIn expectedIn) = Type extractOut expectedOut
where
extractOut (ListLit _ es) = traverse extractIn es
- extractOut _ = Nothing
+ extractOut expr = typeError expectedOut expr
expectedOut = App List expectedIn
@@ -741,8 +806,8 @@ unit :: Type ()
unit = Type extractOut expectedOut
where
extractOut (RecordLit fields)
- | Data.Foldable.null fields = return ()
- extractOut _ = Nothing
+ | Data.Foldable.null fields = pure ()
+ extractOut expr = typeError (Record mempty) expr
expectedOut = Record mempty
@@ -763,10 +828,10 @@ string = Data.Text.Lazy.unpack <$> lazyText
pair :: Type a -> Type b -> Type (a, b)
pair l r = Type extractOut expectedOut
where
- extractOut (RecordLit fields) =
- (,) <$> ( Dhall.Map.lookup "_1" fields >>= extract l )
- <*> ( Dhall.Map.lookup "_2" fields >>= extract r )
- extractOut _ = Nothing
+ extractOut expr@(RecordLit fields) =
+ (,) <$> ( Data.Maybe.maybe (typeError expectedOut expr) (extract l) $ Dhall.Map.lookup "_1" fields)
+ <*> ( Data.Maybe.maybe (typeError expectedOut expr) (extract r) $ Dhall.Map.lookup "_2" fields)
+ extractOut expr = typeError expectedOut expr
expectedOut =
Record
@@ -833,9 +898,10 @@ instance (Inject a, Interpret b) => Interpret (a -> b) where
where
normalizer_ = Just (inputNormalizer opts)
- extractOut e = Just (\i -> case extractIn (Dhall.Core.normalizeWith normalizer_ (App e (embed i))) of
- Just o -> o
- Nothing -> error "Interpret: You cannot decode a function if it does not have the correct type" )
+ -- ToDo
+ extractOut e = pure (\i -> case extractIn (Dhall.Core.normalizeWith normalizer_ (App e (embed i))) of
+ Success o -> o
+ Failure _e -> error "Interpret: You cannot decode a function if it does not have the correct type" )
expectedOut = Pi "_" declared expectedIn
@@ -902,7 +968,7 @@ instance GenericInterpret f => GenericInterpret (M1 D d f) where
instance GenericInterpret V1 where
genericAutoWith _ = pure Type {..}
where
- extract _ = Nothing
+ extract expr = typeError expected expr
expected = Union mempty
@@ -973,11 +1039,13 @@ instance (Constructor c1, Constructor c2, GenericInterpret f1, GenericInterpret
nameR = constructorModifier (Data.Text.pack (conName nR))
extract e0 = do
- (name, e1, _) <- extractUnionConstructor e0
- if
- | name == nameL -> fmap (L1 . M1) (extractL e1)
- | name == nameR -> fmap (R1 . M1) (extractR e1)
- | otherwise -> Nothing
+ case extractUnionConstructor e0 of
+ Just (name, e1, _) ->
+ if
+ | name == nameL -> fmap (L1 . M1) (extractL e1)
+ | name == nameR -> fmap (R1 . M1) (extractR e1)
+ | otherwise -> typeError expected e0
+ _ -> typeError expected e0
expected =
Union
@@ -998,11 +1066,12 @@ instance (Constructor c, GenericInterpret (f :+: g), GenericInterpret h) => Gene
name = constructorModifier (Data.Text.pack (conName n))
- extract u = do
- (name', e, _) <- extractUnionConstructor u
- if
- | name == name' -> fmap (R1 . M1) (extractR e)
- | otherwise -> fmap L1 (extractL u)
+ extract u = case extractUnionConstructor u of
+ Just (name', e, _) ->
+ if
+ | name == name' -> fmap (R1 . M1) (extractR e)
+ | otherwise -> fmap L1 (extractL u)
+ Nothing -> typeError expected u
expected =
Union (Dhall.Map.insert name (notEmptyRecord expectedR) ktsL)
@@ -1020,11 +1089,12 @@ instance (Constructor c, GenericInterpret f, GenericInterpret (g :+: h)) => Gene
name = constructorModifier (Data.Text.pack (conName n))
- extract u = do
- (name', e, _) <- extractUnionConstructor u
- if
- | name == name' -> fmap (L1 . M1) (extractL e)
- | otherwise -> fmap R1 (extractR u)
+ extract u = case extractUnionConstructor u of
+ Just (name', e, _) ->
+ if
+ | name == name' -> fmap (L1 . M1) (extractL e)
+ | otherwise -> fmap R1 (extractR u)
+ _ -> typeError expected u
expected =
Union (Dhall.Map.insert name (notEmptyRecord expectedL) ktsR)
@@ -1037,7 +1107,7 @@ instance (Constructor c, GenericInterpret f, GenericInterpret (g :+: h)) => Gene
instance (GenericInterpret (f :+: g), GenericInterpret (h :+: i)) => GenericInterpret ((f :+: g) :+: (h :+: i)) where
genericAutoWith options = pure (Type {..})
where
- extract e = fmap L1 (extractL e) <|> fmap R1 (extractR e)
+ extract e = fmap L1 (extractL e) `ealt` fmap R1 (extractR e)
expected = Union (Dhall.Map.union ktsL ktsR)
@@ -1055,7 +1125,7 @@ instance GenericInterpret f => GenericInterpret (M1 C c f) where
instance GenericInterpret U1 where
genericAutoWith _ = pure (Type {..})
where
- extract _ = Just U1
+ extract _ = pure U1
expected = Record (Dhall.Map.fromList [])
@@ -1082,15 +1152,17 @@ getSelName n = case selName n of
instance (Selector s, Interpret a) => GenericInterpret (M1 S s (K1 i a)) where
genericAutoWith opts@(InterpretOptions {..}) = do
name <- getSelName n
- let extract (RecordLit m) = do
- let name' = fieldModifier (Data.Text.pack name)
- e <- Dhall.Map.lookup name' m
- fmap (M1 . K1) (extract' e)
- extract _ = Nothing
let expected =
Record (Dhall.Map.fromList [(key, expected')])
where
key = fieldModifier (Data.Text.pack name)
+ let extract expr@(RecordLit m) =
+ let name' = fieldModifier (Data.Text.pack name)
+ extract'' e = fmap (M1 . K1) (extract' e)
+ lookupRes = Dhall.Map.lookup name' m
+ typeError' = typeError expected expr
+ in Data.Maybe.maybe typeError' extract'' lookupRes
+ extract expr = typeError expected expr
pure (Type {..})
where
n :: M1 i s f a
@@ -1240,10 +1312,8 @@ instance Inject () where
instance Inject a => Inject (Maybe a) where
injectWith options = InputType embedOut declaredOut
where
- embedOut (Just x) =
- OptionalLit declaredIn (pure (embedIn x))
- embedOut Nothing =
- OptionalLit declaredIn empty
+ embedOut (Just x ) = Some (embedIn x)
+ embedOut Nothing = App None declaredIn
InputType embedIn declaredIn = injectWith options
@@ -1494,7 +1564,7 @@ newtype RecordType a =
)
( Data.Functor.Compose.Compose
( (->) ( Expr Src X ) )
- Maybe
+ (Extractor Src X)
)
a
)
@@ -1514,15 +1584,12 @@ record ( RecordType ( Data.Functor.Product.Pair ( Control.Applicative.Const fiel
-- | Parse a single field of a record.
field :: Text -> Type a -> RecordType a
-field key valueType =
+field key valueType@(Type extract expected) =
let
- extractBody expr = do
- RecordLit fields <-
- return expr
-
- Dhall.Map.lookup key fields
- >>= extract valueType
-
+ extractBody expr@(RecordLit fields) = case Dhall.Map.lookup key fields of
+ Just v -> extract v
+ _ -> typeError expected expr
+ extractBody expr = typeError expected expr
in
RecordType
( Data.Functor.Product.Pair
@@ -1589,15 +1656,16 @@ union (UnionType (Data.Functor.Compose.Compose mp)) = Type
where
expect = (notEmptyRecord . Dhall.expected) <$> mp
- extractF e0 = do
- (fld, e1, rest) <- extractUnionConstructor e0
-
- t <- Dhall.Map.lookup fld mp
+ extractF e0 =
+ let result = do
+ (fld, e1, rest) <- extractUnionConstructor e0
- guard $ Dhall.Core.Union rest `Dhall.Core.judgmentallyEqual`
- Dhall.Core.Union (Dhall.Map.delete fld expect)
+ t <- Dhall.Map.lookup fld mp
- extract t e1
+ guard $ Dhall.Core.Union rest `Dhall.Core.judgmentallyEqual`
+ Dhall.Core.Union (Dhall.Map.delete fld expect)
+ pure (t, e1)
+ in Data.Maybe.maybe (typeError (Union expect) e0) (uncurry extract) result
-- | Parse a single constructor of a union
constructor :: Text -> Type a -> UnionType a
diff --git a/src/Dhall/Binary.hs b/src/Dhall/Binary.hs
index 87733bb..0d376dc 100644
--- a/src/Dhall/Binary.hs
+++ b/src/Dhall/Binary.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE OverloadedStrings #-}
@@ -43,6 +44,7 @@ import Dhall.Core
, Var(..)
)
+import Dhall.X (X(..))
import Data.Foldable (toList)
import Data.List.NonEmpty (NonEmpty(..))
import Data.Monoid ((<>))
@@ -52,9 +54,11 @@ import Prelude hiding (exponent)
import GHC.Float (double2Float, float2Double)
import qualified Crypto.Hash
+import qualified Control.Monad as Monad
import qualified Data.ByteArray
import qualified Data.ByteString
import qualified Data.Sequence
+import qualified Dhall.Core
import qualified Dhall.Map
import qualified Dhall.Set
import qualified Options.Applicative
@@ -126,11 +130,11 @@ unApply e₀ = (baseFunction₀, diffArguments₀ [])
class ToTerm a where
encode :: a -> Term
-instance ToTerm a => ToTerm (Expr s a) where
+instance ToTerm a => ToTerm (Expr X a) where
encode (Var (V "_" n)) =
- TInteger n
+ TInt n
encode (Var (V x n)) =
- TList [ TString x, TInteger n ]
+ TList [ TString x, TInt n ]
encode NaturalBuild =
TString "Natural/build"
encode NaturalFold =
@@ -280,23 +284,15 @@ instance ToTerm a => ToTerm (Expr s a) where
l₁ = encode l₀
r₁ = encode r₀
encode (ListLit _T₀ xs₀)
- | null xs₀ = TList [ TInt 4, _T₁ ]
+ | null xs₀ = TList [ TInt label, _T₁ ]
| otherwise = TList ([ TInt 4, TNull ] ++ xs₁)
where
- _T₁ = case _T₀ of
- Nothing -> TNull
- Just t -> encode t
+ (label, _T₁) = case _T₀ of
+ Nothing -> (4 , TNull)
+ Just (App List t) -> (4 , encode t)
+ Just t -> (28, encode t)
xs₁ = map encode (Data.Foldable.toList xs₀)
- encode (OptionalLit _T₀ Nothing) =
- TList [ TInt 5, _T₁ ]
- where
- _T₁ = encode _T₀
- encode (OptionalLit _T₀ (Just t₀)) =
- TList [ TInt 5, _T₁, t₁ ]
- where
- _T₁ = encode _T₀
- t₁ = encode t₀
encode (Some t₀) =
TList [ TInt 5, TNull, t₁ ]
where
@@ -423,8 +419,16 @@ instance ToTerm a => ToTerm (Expr s a) where
where
t₁ = encode t₀
_T₁ = encode _T₀
- encode (Note _ e) =
- encode e
+ encode (ToMap t₀ Nothing) =
+ TList [ TInt 27, t₁ ]
+ where
+ t₁ = encode t₀
+ encode (ToMap t₀ (Just _T₀)) =
+ TList [ TInt 27, t₁, _T₁ ]
+ where
+ t₁ = encode t₀
+ _T₁ = encode _T₀
+ encode (Note (X absurd) _) = absurd
instance ToTerm Import where
encode import_ =
@@ -442,7 +446,7 @@ instance ToTerm Import where
Nothing ->
TNull
Just h ->
- encode h
+ encodeExpression h
scheme₁ = case scheme₀ of
HTTP -> 0
@@ -485,21 +489,24 @@ instance ToTerm Import where
Just digest ->
TBytes ("\x12\x20" <> Data.ByteArray.convert digest)
- m = TInt (case importMode of Code -> 0; RawText -> 1)
+ m = TInt (case importMode of Code -> 0; RawText -> 1; Location -> 2;)
Import {..} = import_
ImportHashed {..} = importHashed
+instance ToTerm X where
+ encode = absurd
+
-- | Types that can be decoded from a CBOR `Term`
class FromTerm a where
decode :: Term -> Maybe a
instance FromTerm a => FromTerm (Expr s a) where
decode (TInt n) =
- return (Var (V "_" (fromIntegral n)))
- decode (TInteger n) =
return (Var (V "_" n))
+ decode (TInteger n) =
+ return (Var (V "_" (fromIntegral n)))
decode (TString "Natural/build") =
return NaturalBuild
decode (TString "Natural/fold") =
@@ -564,19 +571,23 @@ instance FromTerm a => FromTerm (Expr s a) where
return (Const Sort)
decode (TString "_") =
empty
- decode (TList [ TString x, TInt n ]) =
- return (Var (V x (fromIntegral n)))
- decode (TList [ TString x, TInteger n ]) =
+ decode (TList [ TString x, TInt n ]) = do
+ Monad.guard (x /= "_")
return (Var (V x n))
+ decode (TList [ TString x, TInteger n ]) = do
+ Monad.guard (x /= "_")
+ return (Var (V x (fromIntegral n)))
decode (TList (TInt 0 : f₁ : xs₁)) = do
f₀ <- decode f₁
xs₀ <- traverse decode xs₁
+ Monad.guard (not (null xs₀))
return (foldl App f₀ xs₀)
decode (TList [ TInt 1, _A₁, b₁ ]) = do
_A₀ <- decode _A₁
b₀ <- decode b₁
return (Lam "_" _A₀ b₀)
decode (TList [ TInt 1, TString x, _A₁, b₁ ]) = do
+ Monad.guard (x /= "_")
_A₀ <- decode _A₁
b₀ <- decode b₁
return (Lam x _A₀ b₀)
@@ -585,6 +596,7 @@ instance FromTerm a => FromTerm (Expr s a) where
_B₀ <- decode _B₁
return (Pi "_" _A₀ _B₀)
decode (TList [ TInt 2, TString x, _A₁, _B₁ ]) = do
+ Monad.guard (x /= "_")
_A₀ <- decode _A₁
_B₀ <- decode _B₁
return (Pi x _A₀ _B₀)
@@ -608,20 +620,13 @@ instance FromTerm a => FromTerm (Expr s a) where
return (op l₀ r₀)
decode (TList [ TInt 4, _T₁ ]) = do
_T₀ <- decode _T₁
- return (ListLit (Just _T₀) empty)
+ return (ListLit (Just (App List _T₀)) empty)
decode (TList (TInt 4 : TNull : xs₁ )) = do
xs₀ <- traverse decode xs₁
return (ListLit Nothing (Data.Sequence.fromList xs₀))
- decode (TList [ TInt 5, _T₁ ]) = do
- _T₀ <- decode _T₁
- return (OptionalLit _T₀ Nothing)
decode (TList [ TInt 5, TNull, t₁ ]) = do
t₀ <- decode t₁
return (Some t₀)
- decode (TList [ TInt 5, _T₁, t₁ ]) = do
- _T₀ <- decode _T₁
- t₀ <- decode t₁
- return (OptionalLit _T₀ (Just t₀))
decode (TList [ TInt 6, t₁, u₁ ]) = do
t₀ <- decode t₁
u₀ <- decode u₁
@@ -717,6 +722,7 @@ instance FromTerm a => FromTerm (Expr s a) where
return (BoolIf t₀ l₀ r₀)
decode (TList [ TInt 15, TInt n ]) = do
+ Monad.guard (0 <= n)
return (NaturalLit (fromIntegral n))
decode (TList [ TInt 15, TInteger n ]) = do
return (NaturalLit (fromInteger n))
@@ -773,6 +779,16 @@ instance FromTerm a => FromTerm (Expr s a) where
t₀ <- decode t₁
_T₀ <- decode _T₁
return (Annot t₀ _T₀)
+ decode (TList [ TInt 27, t₁ ]) = do
+ t₀ <- decode t₁
+ return (ToMap t₀ Nothing)
+ decode (TList [ TInt 27, t₁, _T₁ ]) = do
+ t₀ <- decode t₁
+ _T₀ <- decode _T₁
+ return (ToMap t₀ (Just _T₀))
+ decode (TList [ TInt 28, _T₁ ]) = do
+ _T₀ <- decode _T₁
+ return (ListLit (Just _T₀) empty)
decode _ =
empty
@@ -801,6 +817,7 @@ instance FromTerm Import where
importMode <- case mode of
0 -> return Code
1 -> return RawText
+ 2 -> return Location
_ -> empty
let remote scheme = do
@@ -876,6 +893,9 @@ instance FromTerm Import where
decode _ = empty
+instance FromTerm X where
+ decode _ = empty
+
strip55799Tag :: Term -> Term
strip55799Tag term =
case term of
@@ -921,11 +941,14 @@ strip55799Tag term =
TDouble a
-- | Encode a Dhall expression as a CBOR `Term`
+--
+-- This 'Dhall.Core.denote's the expression before encoding it. To encode an
+-- already denoted expression, it is more efficient to directly use 'encode'.
encodeExpression :: Expr s Import -> Term
-encodeExpression = encode
+encodeExpression e = encode (Dhall.Core.denote e :: Expr X Import)
-- | Decode a Dhall expression from a CBOR `Term`
-decodeExpression :: Term -> Either DecodingFailure (Expr s Import)
+decodeExpression :: FromTerm a => Term -> Either DecodingFailure (Expr s a)
decodeExpression term =
case decodeWithoutVersion <|> decodeWithVersion of
Just expression -> Right expression
@@ -938,7 +961,13 @@ decodeExpression term =
-- For backwards compatibility with older expressions that have a version
-- tag to ease the migration
decodeWithVersion = do
- TList [ TString _, taggedTerm ] <- return strippedTerm
+ TList [ TString version, taggedTerm ] <- return strippedTerm
+
+ -- "_" has never been a valid version string, and this ensures that we
+ -- don't interpret `[ "_", 0 ]` as the expression `_` (encoded as `0`)
+ -- tagged with a version string of `"_"`
+ Monad.guard (version /= "_")
+
decode taggedTerm
data DecodingFailure = CBORIsNotDhall Term
diff --git a/src/Dhall/Context.hs b/src/Dhall/Context.hs
index 3f4f1ee..b44d609 100644
--- a/src/Dhall/Context.hs
+++ b/src/Dhall/Context.hs
@@ -57,7 +57,7 @@ match (Context [] ) = Nothing
> lookup k n (insert k v c) = lookup k (n - 1) c
> lookup k n (insert j v c) = lookup k n c -- k /= j
-}
-lookup :: Text -> Integer -> Context a -> Maybe a
+lookup :: Text -> Int -> Context a -> Maybe a
lookup _ _ (Context [] ) =
Nothing
lookup x n (Context ((k, v):kvs)) =
diff --git a/src/Dhall/Core.hs b/src/Dhall/Core.hs
index 450f1b9..c07a5be 100644
--- a/src/Dhall/Core.hs
+++ b/src/Dhall/Core.hs
@@ -1,5 +1,6 @@
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
+{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveTraversable #-}
@@ -46,6 +47,7 @@ module Dhall.Core (
, isNormalized
, isNormalizedWith
, denote
+ , shallowDenote
, freeIn
-- * Pretty-printing
@@ -68,6 +70,7 @@ module Dhall.Core (
import Control.Applicative (Applicative(..), (<$>))
#endif
import Control.Applicative (empty)
+import Control.DeepSeq (NFData)
import Control.Exception (Exception)
import Control.Monad.IO.Class (MonadIO(..))
import Crypto.Hash (SHA256)
@@ -88,6 +91,8 @@ import Dhall.Set (Set)
import Dhall.Src (Src)
import {-# SOURCE #-} Dhall.Pretty.Internal
import GHC.Generics (Generic)
+import Instances.TH.Lift ()
+import Language.Haskell.TH.Syntax (Lift)
import Numeric.Natural (Natural)
import Prelude hiding (succ)
@@ -126,7 +131,9 @@ import qualified Text.Printf
Dhall is not a dependently typed language
-}
data Const = Type | Kind | Sort
- deriving (Show, Eq, Ord, Data, Bounded, Enum, Generic)
+ deriving (Show, Eq, Ord, Data, Bounded, Enum, Generic, NFData)
+
+instance Lift Const
instance Pretty Const where
pretty = Pretty.unAnnotate . prettyConst
@@ -138,7 +145,7 @@ instance Pretty Const where
@Directory { components = [ "baz", "bar", "foo" ] }@
-}
newtype Directory = Directory { components :: [Text] }
- deriving (Eq, Generic, Ord, Show)
+ deriving (Eq, Generic, Ord, Show, NFData)
instance Semigroup Directory where
Directory components₀ <> Directory components₁ =
@@ -153,7 +160,7 @@ instance Pretty Directory where
data File = File
{ directory :: Directory
, file :: Text
- } deriving (Eq, Generic, Ord, Show)
+ } deriving (Eq, Generic, Ord, Show, NFData)
instance Pretty File where
pretty (File {..}) =
@@ -174,7 +181,7 @@ data FilePrefix
-- ^ Path relative to @..@
| Home
-- ^ Path relative to @~@
- deriving (Eq, Generic, Ord, Show)
+ deriving (Eq, Generic, Ord, Show, NFData)
instance Pretty FilePrefix where
pretty Absolute = ""
@@ -182,7 +189,7 @@ instance Pretty FilePrefix where
pretty Parent = ".."
pretty Home = "~"
-data Scheme = HTTP | HTTPS deriving (Eq, Generic, Ord, Show)
+data Scheme = HTTP | HTTPS deriving (Eq, Generic, Ord, Show, NFData)
data URL = URL
{ scheme :: Scheme
@@ -190,7 +197,7 @@ data URL = URL
, path :: File
, query :: Maybe Text
, headers :: Maybe (Expr Src Import)
- } deriving (Eq, Generic, Ord, Show)
+ } deriving (Eq, Generic, Ord, Show, NFData)
instance Pretty URL where
pretty (URL {..}) =
@@ -228,7 +235,7 @@ data ImportType
| Env Text
-- ^ Environment variable
| Missing
- deriving (Eq, Generic, Ord, Show)
+ deriving (Eq, Generic, Ord, Show, NFData)
parent :: File
parent = File { directory = Directory { components = [ ".." ] }, file = "" }
@@ -266,13 +273,14 @@ instance Pretty ImportType where
pretty Missing = "missing"
-- | How to interpret the import's contents (i.e. as Dhall code or raw text)
-data ImportMode = Code | RawText deriving (Eq, Generic, Ord, Show)
+data ImportMode = Code | RawText | Location
+ deriving (Eq, Generic, Ord, Show, NFData)
-- | A `ImportType` extended with an optional hash for semantic integrity checks
data ImportHashed = ImportHashed
{ hash :: Maybe (Crypto.Hash.Digest SHA256)
, importType :: ImportType
- } deriving (Eq, Generic, Ord, Show)
+ } deriving (Eq, Generic, Ord, Show, NFData)
instance Semigroup ImportHashed where
ImportHashed _ importType₀ <> ImportHashed hash importType₁ =
@@ -288,7 +296,7 @@ instance Pretty ImportHashed where
data Import = Import
{ importHashed :: ImportHashed
, importMode :: ImportMode
- } deriving (Eq, Generic, Ord, Show)
+ } deriving (Eq, Generic, Ord, Show, NFData)
instance Semigroup Import where
Import importHashed₀ _ <> Import importHashed₁ code =
@@ -299,8 +307,9 @@ instance Pretty Import where
where
suffix :: Text
suffix = case importMode of
- RawText -> " as Text"
- Code -> ""
+ RawText -> " as Text"
+ Location -> " as Location"
+ Code -> ""
{-| Label for a bound variable
@@ -334,8 +343,10 @@ instance Pretty Import where
Zero indices are omitted when pretty-printing `Var`s and non-zero indices
appear as a numeric suffix.
-}
-data Var = V Text !Integer
- deriving (Data, Generic, Eq, Ord, Show)
+data Var = V Text !Int
+ deriving (Data, Generic, Eq, Ord, Show, NFData)
+
+instance Lift Var
instance IsString Var where
fromString str = V (fromString str) 0
@@ -422,7 +433,7 @@ data Expr s a
| TextShow
-- | > List ~ List
| List
- -- | > ListLit (Just t ) [x, y, z] ~ [x, y, z] : List t
+ -- | > ListLit (Just t ) [x, y, z] ~ [x, y, z] : t
-- > ListLit Nothing [x, y, z] ~ [x, y, z]
| ListLit (Maybe (Expr s a)) (Seq (Expr s a))
-- | > ListAppend x y ~ x # y
@@ -443,9 +454,6 @@ data Expr s a
| ListReverse
-- | > Optional ~ Optional
| Optional
- -- | > OptionalLit t (Just e) ~ [e] : Optional t
- -- > OptionalLit t Nothing ~ [] : Optional t
- | OptionalLit (Expr s a) (Maybe (Expr s a))
-- | > Some e ~ Some e
| Some (Expr s a)
-- | > None ~ None
@@ -471,6 +479,9 @@ data Expr s a
-- | > Merge x y (Just t ) ~ merge x y : t
-- > Merge x y Nothing ~ merge x y
| Merge (Expr s a) (Expr s a) (Maybe (Expr s a))
+ -- | > ToMap x (Just t) ~ toMap x : t
+ -- > ToMap x Nothing ~ toMap x
+ | ToMap (Expr s a) (Maybe (Expr s a))
-- | > Field e x ~ e.x
| Field (Expr s a) Text
-- | > Project e (Left xs) ~ e.{ xs }
@@ -482,7 +493,11 @@ data Expr s a
| ImportAlt (Expr s a) (Expr s a)
-- | > Embed import ~ import
| Embed a
- deriving (Eq, Ord, Foldable, Generic, Traversable, Show, Data)
+ deriving (Eq, Ord, Foldable, Generic, Traversable, Show, Data, NFData)
+-- NB: If you add a constructor to Expr, please also update the Arbitrary
+-- instance in Dhall.Test.QuickCheck.
+
+instance (Lift s, Lift a, Data s, Data a) => Lift (Expr s a)
-- This instance is hand-written due to the fact that deriving
-- it does not give us an INLINABLE pragma. We annotate this fmap
@@ -536,7 +551,6 @@ instance Functor (Expr s) where
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
@@ -549,6 +563,7 @@ instance Functor (Expr s) where
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 (ToMap e maybeE) = ToMap (fmap f e) (fmap (fmap f) maybeE)
fmap f (Field e1 v) = Field (fmap f e1) v
fmap f (Project e1 vs) = Project (fmap f e1) (fmap (fmap f) vs)
fmap f (Note s e1) = Note s (fmap f e1)
@@ -613,7 +628,6 @@ instance Monad (Expr s) where
ListIndexed >>= _ = ListIndexed
ListReverse >>= _ = ListReverse
Optional >>= _ = Optional
- OptionalLit a b >>= k = OptionalLit (a >>= k) (fmap (>>= k) b)
Some a >>= k = Some (a >>= k)
None >>= _ = None
OptionalFold >>= _ = OptionalFold
@@ -626,6 +640,7 @@ instance Monad (Expr s) where
CombineTypes a b >>= k = CombineTypes (a >>= k) (b >>= k)
Prefer a b >>= k = Prefer (a >>= k) (b >>= k)
Merge a b c >>= k = Merge (a >>= k) (b >>= k) (fmap (>>= k) c)
+ ToMap a b >>= k = ToMap (a >>= k) (fmap (>>= k) b)
Field a b >>= k = Field (a >>= k) b
Project a b >>= k = Project (a >>= k) (fmap (>>= k) b)
Note a b >>= k = Note a (b >>= k)
@@ -680,7 +695,6 @@ instance Bifunctor Expr where
first _ ListIndexed = ListIndexed
first _ ListReverse = ListReverse
first _ Optional = Optional
- first k (OptionalLit a b ) = OptionalLit (first k a) (fmap (first k) b)
first k (Some a ) = Some (first k a)
first _ None = None
first _ OptionalFold = OptionalFold
@@ -693,6 +707,7 @@ instance Bifunctor Expr where
first k (CombineTypes a b ) = CombineTypes (first k a) (first k b)
first k (Prefer a b ) = Prefer (first k a) (first k b)
first k (Merge a b c ) = Merge (first k a) (first k b) (fmap (first k) c)
+ first k (ToMap a b ) = ToMap (first k a) (fmap (first k) b)
first k (Field a b ) = Field (first k a) b
first k (Project a b ) = Project (first k a) (fmap (first k) b)
first k (Note a b ) = Note (k a) (first k b)
@@ -708,7 +723,9 @@ data Binding s a = Binding
{ variable :: Text
, annotation :: Maybe (Expr s a)
, value :: Expr s a
- } deriving (Functor, Foldable, Generic, Traversable, Show, Eq, Ord, Data)
+ } deriving (Functor, Foldable, Generic, Traversable, Show, Eq, Ord, Data, NFData)
+
+instance (Lift s, Lift a, Data s, Data a) => Lift (Binding s a)
instance Bifunctor Binding where
first k (Binding a b c) = Binding a (fmap (first k) b) (first k c)
@@ -717,7 +734,9 @@ instance Bifunctor Binding where
-- | The body of an interpolated @Text@ literal
data Chunks s a = Chunks [(Text, Expr s a)] Text
- deriving (Functor, Foldable, Generic, Traversable, Show, Eq, Ord, Data)
+ deriving (Functor, Foldable, Generic, Traversable, Show, Eq, Ord, Data, NFData)
+
+instance (Lift s, Lift a, Data s, Data a) => Lift (Chunks s a)
instance Data.Semigroup.Semigroup (Chunks s a) where
Chunks xysL zL <> Chunks [] zR =
@@ -811,7 +830,7 @@ instance Pretty a => Pretty (Expr s a) where
descend into a lambda or let expression that binds a variable of the same
name in order to avoid shifting the bound variables by mistake.
-}
-shift :: Integer -> Var -> Expr s a -> Expr s a
+shift :: Int -> Var -> Expr s a -> Expr s a
shift _ _ (Const a) = Const a
shift d (V x n) (Var (V x' n')) = Var (V x' n'')
where
@@ -928,10 +947,6 @@ shift _ _ ListLast = ListLast
shift _ _ ListIndexed = ListIndexed
shift _ _ ListReverse = ListReverse
shift _ _ Optional = Optional
-shift d v (OptionalLit a b) = OptionalLit a' b'
- where
- a' = shift d v a
- b' = fmap (shift d v) b
shift d v (Some a) = Some a'
where
a' = shift d v a
@@ -968,12 +983,17 @@ shift d v (Merge a b c) = Merge a' b' c'
a' = shift d v a
b' = shift d v b
c' = fmap (shift d v) c
+shift d v (ToMap a b) = ToMap a' b'
+ where
+ a' = shift d v a
+ b' = fmap (shift d v) b
shift d v (Field a b) = Field a' b
where
a' = shift d v a
-shift d v (Project a b) = Project a' b
+shift d v (Project a b) = Project a' b'
where
- a' = shift d v a
+ a' = shift d v a
+ b' = fmap (shift d v) b
shift d v (Note a b) = Note a b'
where
b' = shift d v b
@@ -1106,10 +1126,6 @@ subst _ _ ListLast = ListLast
subst _ _ ListIndexed = ListIndexed
subst _ _ ListReverse = ListReverse
subst _ _ Optional = Optional
-subst x e (OptionalLit a b) = OptionalLit a' b'
- where
- a' = subst x e a
- b' = fmap (subst x e) b
subst x e (Some a) = Some a'
where
a' = subst x e a
@@ -1146,12 +1162,17 @@ subst x e (Merge a b c) = Merge a' b' c'
a' = subst x e a
b' = subst x e b
c' = fmap (subst x e) c
+subst x e (ToMap a b) = ToMap a' b'
+ where
+ a' = subst x e a
+ b' = fmap (subst x e) b
subst x e (Field a b) = Field a' b
where
a' = subst x e a
-subst x e (Project a b) = Project a' b
+subst x e (Project a b) = Project a' b'
where
- a' = subst x e a
+ a' = subst x e a
+ b' = fmap (subst x e) b
subst x e (Note a b) = Note a b'
where
b' = subst x e b
@@ -1184,8 +1205,8 @@ alphaNormalize = Dhall.Eval.alphaNormalize
expressions before normalizing them since normalization can convert an
ill-typed expression into a well-typed expression.
- However, `normalize` will not fail if the expression is ill-typed and will
- leave ill-typed sub-expressions unevaluated.
+ `normalize` can also fail with `error` if you normalize an ill-typed
+ expression
-}
normalize :: Eq a => Expr s a -> Expr t a
@@ -1266,7 +1287,6 @@ denote ListLast = ListLast
denote ListIndexed = ListIndexed
denote ListReverse = ListReverse
denote Optional = Optional
-denote (OptionalLit a b ) = OptionalLit (denote a) (fmap denote b)
denote (Some a ) = Some (denote a)
denote None = None
denote OptionalFold = OptionalFold
@@ -1279,11 +1299,16 @@ 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)
denote (Merge a b c ) = Merge (denote a) (denote b) (fmap denote c)
+denote (ToMap a b ) = ToMap (denote a) (fmap denote b)
denote (Field a b ) = Field (denote a) b
denote (Project a b ) = Project (denote a) (fmap denote b)
denote (ImportAlt a b ) = ImportAlt (denote a) (denote b)
denote (Embed a ) = Embed a
+shallowDenote :: Expr s a -> Expr s a
+shallowDenote (Note _ e) = shallowDenote e
+shallowDenote e = e
+
{-| Reduce an expression to its normal form, performing beta reduction and applying
any custom definitions.
@@ -1298,11 +1323,19 @@ denote (Embed a ) = Embed a
That is, if the functions in custom context are not total then the Dhall language, evaluated
with those functions is not total either.
+ `normalizeWith` can fail with an `error` if you normalize an ill-typed
+ expression
-}
normalizeWith :: Eq a => Maybe (ReifiedNormalizer a) -> Expr s a -> Expr t a
normalizeWith (Just ctx) t = runIdentity (normalizeWithM (getReifiedNormalizer ctx) t)
normalizeWith _ t = Dhall.Eval.nfEmpty t
+{-| This function generalizes `normalizeWith` by allowing the custom normalizer
+ to use an arbitrary `Monad`
+
+ `normalizeWithM` can fail with an `error` if you normalize an ill-typed
+ expression
+-}
normalizeWithM
:: (Monad m, Eq a) => NormalizerM m a -> Expr s a -> m (Expr t a)
normalizeWithM ctx e0 = loop (denote e0)
@@ -1338,6 +1371,20 @@ normalizeWithM ctx e0 = loop (denote e0)
-- build/fold fusion for `List`
App (App ListBuild _) (App (App ListFold _) e') -> loop e'
+ App NaturalFold (NaturalLit n) -> do
+ let natural = Var (V "natural" 0)
+ let go 0 x = x
+ go n' x = go (n'-1) (App (Var (V "succ" 0)) x)
+ let n' = go n (Var (V "zero" 0))
+ pure
+ (Lam "natural"
+ (Const Type)
+ (Lam "succ"
+ (Pi "_" natural natural)
+ (Lam "zero"
+ natural
+ n')))
+
-- build/fold fusion for `Natural`
App NaturalBuild (App NaturalFold e') -> loop e'
@@ -1358,7 +1405,7 @@ normalizeWithM ctx e0 = loop (denote e0)
lazyLoop !n = App succ' (lazyLoop (n - 1))
App NaturalBuild g -> loop (App (App (App g Natural) succ) zero)
where
- succ = Lam "x" Natural (NaturalPlus "x" (NaturalLit 1))
+ succ = Lam "n" Natural (NaturalPlus "n" (NaturalLit 1))
zero = NaturalLit 0
App NaturalIsZero (NaturalLit n) -> pure (BoolLit (n == 0))
@@ -1395,7 +1442,7 @@ normalizeWithM ctx e0 = loop (denote e0)
(ListAppend (ListLit Nothing (pure "a")) "as")
)
- nil = ListLit (Just _A₀) empty
+ nil = ListLit (Just (App List _A₀)) empty
App (App (App (App (App ListFold _) (ListLit _ xs)) t) cons) nil -> do
t' <- loop t
if boundedType t' then strict else lazy
@@ -1421,7 +1468,7 @@ normalizeWithM ctx e0 = loop (denote e0)
o = case Data.Sequence.viewr ys of
_ :> y -> Some y
_ -> App None t
- App (App ListIndexed _A₀) (ListLit _A₁ as₀) -> loop (ListLit t as₁)
+ App (App ListIndexed _A₀) (ListLit _ as₀) -> loop (ListLit t as₁)
where
as₁ = Data.Sequence.mapWithIndex adapt as₀
@@ -1431,7 +1478,7 @@ normalizeWithM ctx e0 = loop (denote e0)
, ("value", _A₀)
]
- t | null as₀ = Just _A₂
+ t | null as₀ = Just (App List _A₂)
| otherwise = Nothing
adapt n a_ =
@@ -1443,7 +1490,7 @@ normalizeWithM ctx e0 = loop (denote e0)
App (App ListReverse t) (ListLit _ xs) ->
loop (ListLit m (Data.Sequence.reverse xs))
where
- m = if Data.Sequence.null xs then Just t else Nothing
+ m = if Data.Sequence.null xs then Just (App List t) else Nothing
App (App (App (App (App OptionalFold _) (App None _)) _) _) nothing ->
loop nothing
App (App (App (App (App OptionalFold _) (Some x)) _) just) _ ->
@@ -1580,8 +1627,6 @@ normalizeWithM ctx e0 = loop (denote e0)
ListIndexed -> pure ListIndexed
ListReverse -> pure ListReverse
Optional -> pure Optional
- OptionalLit _A Nothing -> loop (App None _A)
- OptionalLit _ (Just a) -> loop (Some a)
Some a -> Some <$> a'
where
a' = loop a
@@ -1661,6 +1706,30 @@ normalizeWithM ctx e0 = loop (denote e0)
_ -> Merge x' y' <$> t'
where
t' = traverse loop t
+ ToMap x t -> do
+ x' <- loop x
+ t' <- traverse loop t
+ case x' of
+ RecordLit kvsX -> do
+ let entry (key, value) =
+ RecordLit
+ (Dhall.Map.fromList
+ [ ("mapKey" , TextLit (Chunks [] key))
+ , ("mapValue", value )
+ ]
+ )
+
+ let keyValues = Data.Sequence.fromList (map entry (Dhall.Map.toList kvsX))
+
+ let listType = case t' of
+ Just _ | null keyValues ->
+ t'
+ _ ->
+ Nothing
+
+ return (ListLit listType keyValues)
+ _ -> do
+ return (ToMap x' t')
Field r x -> do
r' <- loop r
case r' of
@@ -1673,25 +1742,15 @@ normalizeWithM ctx e0 = loop (denote e0)
r' <- loop r
case r' of
RecordLit kvs ->
- case traverse adapt (Dhall.Set.toList xs) of
- Just s ->
- loop (RecordLit kvs')
- where
- kvs' = Dhall.Map.fromList s
- Nothing ->
- Project <$> (RecordLit <$> traverse loop kvs) <*> pure (Left xs)
- where
- adapt x = do
- v <- Dhall.Map.lookup x kvs
- return (x, v)
+ pure (RecordLit (Dhall.Map.restrictKeys kvs (Dhall.Set.toSet xs)))
_ | null xs -> pure (RecordLit mempty)
- | otherwise -> pure (Project r' (Left xs))
+ | otherwise -> pure (Project r' (Left (Dhall.Set.sort xs)))
Project r (Right e1) -> do
e2 <- loop e1
case e2 of
Record kts -> do
- loop (Project r (Left (Dhall.Set.fromList (Dhall.Map.keys kts))))
+ loop (Project r (Left (Dhall.Set.fromSet (Dhall.Map.keysSet kts))))
_ -> do
r' <- loop r
pure (Project r' (Right e2))
@@ -1715,6 +1774,9 @@ textShow text = "\"" <> Data.Text.concatMap f text <> "\""
{-| Returns `True` if two expressions are α-equivalent and β-equivalent and
`False` otherwise
+
+ `judgmentallyEqual` can fail with an `error` if you compare ill-typed
+ expressions
-}
judgmentallyEqual :: Eq a => Expr s a -> Expr t a -> Bool
judgmentallyEqual = Dhall.Eval.convEmpty
@@ -1734,10 +1796,19 @@ newtype ReifiedNormalizer a = ReifiedNormalizer
-- Unlike `isNormalized`, this will fully normalize and traverse through the expression.
--
-- It is much more efficient to use `isNormalized`.
+--
+-- `isNormalizedWith` can fail with an `error` if you check an ill-typed
+-- expression
isNormalizedWith :: (Eq s, Eq a) => Normalizer a -> Expr s a -> Bool
isNormalizedWith ctx e = e == normalizeWith (Just (ReifiedNormalizer ctx)) e
-- | Quickly check if an expression is in normal form
+--
+-- Given a well-typed expression @e@, @'isNormalized' e@ is equivalent to
+-- @e == 'normalize' e@.
+--
+-- Given an ill-typed expression, 'isNormalized' may fail with an error, or
+-- evaluate to either False or True!
isNormalized :: Eq a => Expr s a -> Bool
isNormalized e0 = loop (denote e0)
where
@@ -1759,6 +1830,7 @@ isNormalized e0 = loop (denote e0)
App (App OptionalBuild _) (App (App OptionalFold _) _) -> False
App (App (App (App NaturalFold (NaturalLit _)) _) _) _ -> False
+ App NaturalFold (NaturalLit _) -> False
App NaturalBuild _ -> False
App NaturalIsZero (NaturalLit _) -> False
App NaturalEven (NaturalLit _) -> False
@@ -1869,7 +1941,6 @@ isNormalized e0 = loop (denote e0)
ListIndexed -> True
ListReverse -> True
Optional -> True
- OptionalLit _ _ -> False
Some a -> loop a
None -> True
OptionalFold -> True
@@ -1906,29 +1977,20 @@ isNormalized e0 = loop (denote e0)
Nothing -> True
_ -> True
_ -> True
- Field r x -> loop r &&
- case r of
- RecordLit kvs ->
- case Dhall.Map.lookup x kvs of
- Just _ -> False
- Nothing -> True
- Union kvs ->
- case Dhall.Map.lookup x kvs of
- Just _ -> False
- Nothing -> True
- _ -> True
- Project r xs -> loop r &&
- case r of
- RecordLit kvs ->
- case xs of
- Left s -> not (all (flip Dhall.Map.member kvs) s)
- Right e' ->
- case e' of
- Record kts ->
- loop (Project r (Left (Dhall.Set.fromList (Dhall.Map.keys kts))))
- _ ->
- False
- _ -> not (null xs)
+ ToMap x t -> case x of
+ RecordLit _ -> False
+ _ -> loop x && all loop t
+ Field r _ -> case r of
+ RecordLit _ -> False
+ _ -> loop r
+ Project r p -> loop r &&
+ case p of
+ Left s -> case r of
+ RecordLit _ -> False
+ _ -> not (Dhall.Set.null s) && Dhall.Set.isSorted s
+ Right e' -> case e' of
+ Record _ -> False
+ _ -> loop e'
Note _ e' -> loop e'
ImportAlt l _r -> loop l
Embed _ -> True
@@ -1943,8 +2005,9 @@ False
False
-}
freeIn :: Eq a => Var -> Expr s a -> Bool
-variable `freeIn` expression =
- Dhall.Core.shift 1 variable strippedExpression /= strippedExpression
+variable@(V var i) `freeIn` expression =
+ Dhall.Core.subst variable (Var (V var (i + 1))) strippedExpression
+ /= strippedExpression
where
denote' :: Expr t b -> Expr () b
denote' = denote
@@ -1988,12 +2051,12 @@ reservedIdentifiers =
, "True"
, "False"
, "merge"
+ , "toMap"
, "if"
, "then"
, "else"
, "as"
, "using"
- , "constructors"
, "Natural"
, "Natural/fold"
, "Natural/build"
@@ -2079,7 +2142,6 @@ subExpressions _ ListLast = pure ListLast
subExpressions _ ListIndexed = pure ListIndexed
subExpressions _ ListReverse = pure ListReverse
subExpressions _ Optional = pure Optional
-subExpressions f (OptionalLit a b) = OptionalLit <$> f a <*> traverse f b
subExpressions f (Some a) = Some <$> f a
subExpressions _ None = pure None
subExpressions _ OptionalFold = pure OptionalFold
@@ -2093,8 +2155,9 @@ 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
subExpressions f (Merge a b t) = Merge <$> f a <*> f b <*> traverse f t
+subExpressions f (ToMap a t) = ToMap <$> f a <*> traverse f t
subExpressions f (Field a b) = Field <$> f a <*> pure b
-subExpressions f (Project a b) = Project <$> f a <*> pure b
+subExpressions f (Project a b) = Project <$> f a <*> traverse f b
subExpressions f (Note a b) = Note a <$> f b
subExpressions f (ImportAlt l r) = ImportAlt <$> f l <*> f r
subExpressions _ (Embed a) = pure (Embed a)
diff --git a/src/Dhall/Diff.hs b/src/Dhall/Diff.hs
index a36ab18..6658415 100644
--- a/src/Dhall/Diff.hs
+++ b/src/Dhall/Diff.hs
@@ -18,7 +18,6 @@ module Dhall.Diff (
) where
import Data.Foldable (fold, toList)
-import Data.Function (on)
import Data.List.NonEmpty (NonEmpty(..))
import Data.Monoid (Any(..))
import Data.Semigroup
@@ -207,12 +206,15 @@ diffBool = diffPrimitive bool
diffInteger :: Integer -> Integer -> Diff
diffInteger = diffPrimitive (token . Internal.prettyNumber)
+diffInt :: Int -> Int -> Diff
+diffInt = diffPrimitive (token . Internal.prettyInt)
+
diffVar :: Var -> Var -> Diff
diffVar (V xL nL) (V xR nR) = format mempty label <> "@" <> natural
where
label = diffLabel xL xR
- natural = diffInteger nL nR
+ natural = diffInt nL nR
diffPretty :: (Eq a, Pretty a) => a -> a -> Diff
diffPretty = diffPrimitive (token . Pretty.pretty)
@@ -267,8 +269,8 @@ diffKeysWith
diffKeysWith assign diffVals kvsL kvsR =
diffFieldNames <> diffFieldValues <> (if anyEqual then [ ignore ] else [])
where
- ksL = Data.Set.fromList (Dhall.Map.keys kvsL)
- ksR = Data.Set.fromList (Dhall.Map.keys kvsR)
+ ksL = Dhall.Map.keysSet kvsL
+ ksR = Dhall.Map.keysSet kvsR
extraL = Data.Set.difference ksL ksR
extraR = Data.Set.difference ksR ksL
@@ -570,8 +572,6 @@ skeleton (ListLit {}) =
<> " "
<> colon
<> " "
- <> builtin "List"
- <> " "
<> ignore
skeleton (ListAppend {}) =
ignore
@@ -579,18 +579,6 @@ skeleton (ListAppend {}) =
<> operator "#"
<> " "
<> ignore
-skeleton (OptionalLit {}) =
- lbracket
- <> " "
- <> ignore
- <> " "
- <> rbracket
- <> " "
- <> colon
- <> " "
- <> builtin "Optional"
- <> " "
- <> ignore
skeleton (Record {}) =
lbrace
<> " "
@@ -655,6 +643,10 @@ skeleton (Merge {}) =
<> ignore
<> " "
<> ignore
+skeleton (ToMap {}) =
+ keyword "toMap"
+ <> " "
+ <> ignore
skeleton (Field {}) =
ignore
<> dot
@@ -770,29 +762,24 @@ diffAnnotatedExpression l@(Merge {}) r =
mismatch l r
diffAnnotatedExpression l r@(Merge {}) =
mismatch l r
+diffAnnotatedExpression (ToMap aL bL) (ToMap aR bR) = align doc
+ where
+ doc = keyword "toMap"
+ <> " "
+ <> format " " (diffImportExpression aL aR)
+ <> diffMaybe (colon <> " ") diffApplicationExpression bL bR
+diffAnnotatedExpression l@(ToMap {}) r =
+ mismatch l r
+diffAnnotatedExpression l r@(ToMap {}) =
+ mismatch l r
diffAnnotatedExpression (ListLit aL@(Just _) bL) (ListLit aR bR) = align doc
where
doc = format " " (diffList bL bR)
- <> format " " (diffMaybe (colon <> " ") (diffApplicationExpression `on` App List) aL aR)
+ <> format " " (diffMaybe (colon <> " ") diffApplicationExpression aL aR)
diffAnnotatedExpression (ListLit aL bL) (ListLit aR@(Just _) bR) = align doc
where
doc = format " " (diffList bL bR)
- <> format " " (diffMaybe (colon <> " ") (diffApplicationExpression `on` App List) aL aR)
-diffAnnotatedExpression (OptionalLit aL bL) (OptionalLit aR bR) =
- align doc
- where
- doc = lbracket
- <> " "
- <> format " " (diffMaybe mempty diffExpression bL bR)
- <> rbracket
- <> " "
- <> colon
- <> " "
- <> diffApplicationExpression (App Optional aL) (App Optional aR)
-diffAnnotatedExpression l@(OptionalLit {}) r =
- mismatch l r
-diffAnnotatedExpression l r@(OptionalLit {}) =
- mismatch l r
+ <> format " " (diffMaybe (colon <> " ") diffApplicationExpression aL aR)
diffAnnotatedExpression l@(Annot {}) r@(Annot {}) =
enclosed' " " (colon <> " ") (docs l r)
where
@@ -1166,10 +1153,6 @@ diffPrimitiveExpression l r@List =
diffPrimitiveExpression (ListLit Nothing bL) (ListLit Nothing bR) = align doc
where
doc = format " " (diffList bL bR)
-diffPrimitiveExpression l@(ListLit {}) r =
- mismatch l r
-diffPrimitiveExpression l r@(ListLit {}) =
- mismatch l r
diffPrimitiveExpression ListBuild ListBuild =
"…"
diffPrimitiveExpression l@ListBuild r =
diff --git a/src/Dhall/Eval.hs b/src/Dhall/Eval.hs
index 6303dc7..bc6620c 100644
--- a/src/Dhall/Eval.hs
+++ b/src/Dhall/Eval.hs
@@ -78,6 +78,7 @@ import Dhall.Core (
-- import Dhall.Import.Types (InternalError)
import Dhall.Map (Map)
import Dhall.Set (Set)
+import Dhall.X (X)
import GHC.Natural (Natural)
import Unsafe.Coerce (unsafeCoerce)
@@ -213,6 +214,7 @@ data Val a
| VCombineTypes !(Val a) !(Val a)
| VPrefer !(Val a) !(Val a)
| VMerge !(Val a) !(Val a) !(Maybe (Val a))
+ | VToMap !(Val a) !(Maybe (Val a))
| VField !(Val a) !Text
| VInject !(Map Text (Maybe (Val a))) !Text !(Maybe (Val a))
| VProject !(Val a) !(Either (Set Text) (Val a))
@@ -251,7 +253,7 @@ inst (Cl x env t) !u = eval (Extend env x u) t
-- Out-of-env variables have negative de Bruijn levels.
vVar :: Env a -> Var -> Val a
-vVar env (V x (fromInteger -> i :: Int)) = go env i where
+vVar env (V x i) = go env i where
go (Extend env x' v) i
| x == x' = if i == 0 then v else go env (i - 1)
| otherwise = go env i
@@ -436,7 +438,7 @@ eval !env t =
`vApp` VHLam (Typed "a" a) (\x ->
VHLam (Typed "as" (VList a)) (\as ->
vListAppend (VListLit Nothing (pure x)) as))
- `vApp` VListLit (Just a) mempty
+ `vApp` VListLit (Just (VList a)) mempty
ListFold -> VPrim $ \a -> VPrim $ \case
VListLit _ as ->
@@ -464,8 +466,8 @@ eval !env t =
ListIndexed -> VPrim $ \ a -> VPrim $ \case
VListLit _ as -> let
a' = if null as then
- Just (VRecord (Dhall.Map.fromList
- [("index", VNatural), ("value", a)]))
+ Just (VList (VRecord (Dhall.Map.fromList
+ [("index", VNatural), ("value", a)])))
else
Nothing
as' = Data.Sequence.mapWithIndex
@@ -481,7 +483,6 @@ eval !env t =
t -> VListReverse a t
Optional -> VPrim VOptional
- OptionalLit a mt -> maybe (VNone (evalE a)) (\t -> VSome (evalE t)) mt
Some t -> VSome (evalE t)
None -> VPrim $ \ ~a -> VNone a
@@ -528,6 +529,16 @@ eval !env t =
| Just f <- Dhall.Map.lookup k m -> maybe f (vApp f) mt
| otherwise -> error errorMsg
(x, y, ma) -> VMerge x y ma
+ ToMap x ma -> case (evalE x, evalE <$> ma) of
+ (VRecordLit m, ma'@(Just _)) | null m ->
+ VListLit ma' (Data.Sequence.empty)
+ (VRecordLit m, _) -> let
+ entry (k, v) =
+ VRecordLit (Dhall.Map.fromList [("mapKey", VTextLit $ VChunks [] k),
+ ("mapValue", v)])
+ s = (Data.Sequence.fromList . map entry . Dhall.Map.toList) m
+ in VListLit Nothing s
+ (x, ma) -> VToMap x ma
Field t k -> case evalE t of
VRecordLit m
| Just v <- Dhall.Map.lookup k m -> v
@@ -541,15 +552,14 @@ eval !env t =
if null ks then
VRecordLit mempty
else case evalE t of
- VRecordLit kvs
- | Just s <- traverse (\k -> (k,) <$> Dhall.Map.lookup k kvs) (toList ks)
- -> VRecordLit (Dhall.Map.sort (Dhall.Map.fromList s))
- | otherwise -> error errorMsg
- t -> VProject t (Left ks)
+ VRecordLit kvs -> let
+ kvs' = Dhall.Map.restrictKeys kvs (Dhall.Set.toSet ks)
+ in VRecordLit (Dhall.Map.sort kvs')
+ t -> VProject t (Left (Dhall.Set.sort ks))
Project t (Right e) ->
case evalE e of
VRecord kts ->
- evalE (Project t (Left (Dhall.Set.fromList (Dhall.Map.keys kts))))
+ evalE (Project t (Left (Dhall.Set.fromSet (Dhall.Map.keysSet kts))))
e' -> VProject (evalE t) (Right e')
Note _ e -> evalE e
ImportAlt t _ -> evalE t
@@ -567,7 +577,9 @@ eqListBy f = go where
{-# inline eqListBy #-}
eqMapsBy :: Ord k => (v -> v -> Bool) -> Map k v -> Map k v -> Bool
-eqMapsBy f mL mR = eqListBy eq (Dhall.Map.toList mL) (Dhall.Map.toList mR)
+eqMapsBy f mL mR =
+ Dhall.Map.size mL == Dhall.Map.size mR
+ && eqListBy eq (Dhall.Map.toList mL) (Dhall.Map.toList mR)
where
eq (kL, vL) (kR, vR) = kL == kR && f vL vR
{-# inline eqMapsBy #-}
@@ -656,8 +668,8 @@ conv !env t t' =
(VIntegerToDouble t , VIntegerToDouble t') -> convE t t'
(VDouble , VDouble) -> True
- (VDoubleLit n , VDoubleLit n') -> Dhall.Binary.encode (DoubleLit n :: Expr Void Import) ==
- Dhall.Binary.encode (DoubleLit n' :: Expr Void Import)
+ (VDoubleLit n , VDoubleLit n') -> Dhall.Binary.encode (DoubleLit n :: Expr X Import) ==
+ Dhall.Binary.encode (DoubleLit n' :: Expr X Import)
(VDoubleShow t , VDoubleShow t') -> convE t t'
(VText, VText) -> True
@@ -692,6 +704,7 @@ conv !env t t' =
(VCombineTypes t u , VCombineTypes t' u' ) -> convE t t' && convE u u'
(VPrefer t u , VPrefer t' u' ) -> convE t t' && convE u u'
(VMerge t u _ , VMerge t' u' _ ) -> convE t t' && convE u u'
+ (VToMap t _ , VToMap t' _ ) -> convE t t'
(VField t k , VField t' k' ) -> convE t t' && k == k'
(VProject t (Left ks) , VProject t' (Left ks') ) -> convE t t' && ks == ks'
(VProject t (Right e) , VProject t' (Right e') ) -> convE t t' && convE e e'
@@ -826,6 +839,7 @@ quote !env !t =
VCombineTypes t u -> CombineTypes (quoteE t) (quoteE u)
VPrefer t u -> Prefer (quoteE t) (quoteE u)
VMerge t u ma -> Merge (quoteE t) (quoteE u) (quoteE <$> ma)
+ VToMap t ma -> ToMap (quoteE t) (quoteE <$> ma)
VField t k -> Field (quoteE t) k
VProject t p -> Project (quoteE t) (fmap quoteE p)
VInject m k Nothing -> Field (Union ((quoteE <$>) <$> m)) k
@@ -852,7 +866,7 @@ nfEmpty = nf Empty
alphaNormalize :: Expr s a -> Expr s a
alphaNormalize = goEnv NEmpty where
- goVar :: Names -> Text -> Integer -> Expr s a
+ goVar :: Names -> Text -> Int -> Expr s a
goVar e topX topI = go 0 e topI where
go !acc (NBind env x) !i
| x == topX = if i == 0 then Var (V "_" acc) else go (acc + 1) env (i - 1)
@@ -926,7 +940,6 @@ alphaNormalize = goEnv NEmpty where
ListIndexed -> ListIndexed
ListReverse -> ListReverse
Optional -> Optional
- OptionalLit a mt -> OptionalLit (go a) (go <$> mt)
Some t -> Some (go t)
None -> None
OptionalFold -> OptionalFold
@@ -939,8 +952,9 @@ alphaNormalize = goEnv NEmpty where
CombineTypes t u -> CombineTypes (go t) (go u)
Prefer t u -> Prefer (go t) (go u)
Merge x y ma -> Merge (go x) (go y) (go <$> ma)
+ ToMap x ma -> ToMap (go x) (go <$> ma)
Field t k -> Field (go t) k
- Project t ks -> Project (go t) ks
+ Project t ks -> Project (go t) (go <$> ks)
Note s e -> Note s (go e)
ImportAlt t u -> ImportAlt (go t) (go u)
Embed a -> Embed a
diff --git a/src/Dhall/Freeze.hs b/src/Dhall/Freeze.hs
index b120e1e..a368fa7 100644
--- a/src/Dhall/Freeze.hs
+++ b/src/Dhall/Freeze.hs
@@ -77,14 +77,14 @@ freezeImport directory _standardVersion import_ = do
let normalizedExpression =
Dhall.Core.alphaNormalize (Dhall.Core.normalize expression)
- let expressionHash =
- Just (Dhall.Import.hashExpression _standardVersion normalizedExpression)
+ -- make sure the frozen import is present in the semantic cache
+ Dhall.Import.writeExpressionToSemanticCache expression
- let newImportHashed = (importHashed import_) { hash = expressionHash }
+ let expressionHash = Dhall.Import.hashExpression _standardVersion normalizedExpression
- let newImport = import_ { importHashed = newImportHashed }
+ let newImportHashed = (importHashed import_) { hash = Just expressionHash }
- State.evalStateT (Dhall.Import.exprToImport newImport normalizedExpression) status
+ let newImport = import_ { importHashed = newImportHashed }
return newImport
diff --git a/src/Dhall/Import.hs b/src/Dhall/Import.hs
index a20ebd7..406f125 100644
--- a/src/Dhall/Import.hs
+++ b/src/Dhall/Import.hs
@@ -100,23 +100,30 @@
module Dhall.Import (
-- * Import
- exprFromImport
- , exprToImport
- , load
+ load
, loadWith
+ , localToPath
, hashExpression
, hashExpressionToCode
+ , writeExpressionToSemanticCache
, assertNoImports
, Status
+ , Chained
+ , chainedImport
+ , chainedFromLocalHere
+ , chainedChangeMode
, emptyStatus
, stack
, cache
- , manager
+ , Depends(..)
+ , graph
+ , remote
+ , toHeaders
, standardVersion
, normalizer
, startingContext
- , resolver
- , cacher
+ , chainImport
+ , ImportSemantics
, Cycle(..)
, ReferentiallyOpaque(..)
, Imported(..)
@@ -130,12 +137,14 @@ module Dhall.Import (
import Control.Applicative (Alternative(..))
import Codec.CBOR.Term (Term(..))
-import Control.Exception (Exception, SomeException, throwIO, toException)
+import Control.Exception (Exception, SomeException, toException)
import Control.Monad (guard)
-import Control.Monad.Catch (throwM, MonadCatch(catch), catches, Handler(..))
+import Control.Monad.Catch (throwM, MonadCatch(catch), handle)
import Control.Monad.IO.Class (MonadIO(..))
+import Control.Monad.Trans.Class (lift)
import Control.Monad.Trans.State.Strict (StateT)
import Crypto.Hash (SHA256)
+import Data.ByteString (ByteString)
import Data.CaseInsensitive (CI)
import Data.List.NonEmpty (NonEmpty(..))
import Data.Semigroup (Semigroup(..))
@@ -161,10 +170,10 @@ import Dhall.Core
, URL(..)
)
#ifdef MIN_VERSION_http_client
-import Dhall.Import.HTTP
+import Network.HTTP.Client (Manager)
+import Dhall.Import.HTTP hiding (HTTPHeader)
#endif
import Dhall.Import.Types
-import Text.Dot ((.->.), userNodeId)
import Dhall.Parser (Parser(..), ParseError(..), Src(..), SourcedException(..))
import Dhall.TypeCheck (X(..))
@@ -246,8 +255,8 @@ instance Show ReferentiallyOpaque where
-- | Extend another exception with the current import stack
data Imported e = Imported
- { importStack :: NonEmpty Import -- ^ Imports resolved so far, in reverse order
- , nested :: e -- ^ The nested exception
+ { importStack :: NonEmpty Chained -- ^ Imports resolved so far, in reverse order
+ , nested :: e -- ^ The nested exception
} deriving (Typeable)
instance Exception e => Exception (Imported e)
@@ -311,12 +320,14 @@ instance Show MissingImports where
throwMissingImport :: (MonadCatch m, Exception e) => e -> m a
throwMissingImport e = throwM (MissingImports [toException e])
+type HTTPHeader = (CI ByteString, ByteString)
+
-- | Exception thrown when a HTTP url is imported but dhall was built without
-- the @with-http@ Cabal flag.
data CannotImportHTTPURL =
CannotImportHTTPURL
String
- (Maybe [(CI Data.ByteString.ByteString, Data.ByteString.ByteString)])
+ (Maybe [HTTPHeader])
deriving (Typeable)
instance Exception CannotImportHTTPURL
@@ -335,7 +346,7 @@ instance Show CannotImportHTTPURL where
{-|
> canonicalize . canonicalize = canonicalize
-> canonicalize (a <> b) = canonicalize a <> canonicalize b
+> canonicalize (a <> b) = canonicalize (canonicalize a <> canonicalize b)
-}
class Semigroup path => Canonicalize path where
canonicalize :: path -> path
@@ -388,28 +399,6 @@ instance Canonicalize Import where
canonicalize (Import importHashed importMode) =
Import (canonicalize importHashed) importMode
-toHeaders
- :: Expr s a
- -> Maybe [(CI Data.ByteString.ByteString, Data.ByteString.ByteString)]
-toHeaders (ListLit _ hs) = do
- hs' <- mapM toHeader hs
- return (Data.Foldable.toList hs')
-toHeaders _ = do
- empty
-
-toHeader
- :: Expr s a
- -> Maybe (CI Data.ByteString.ByteString, Data.ByteString.ByteString)
-toHeader (RecordLit m) = do
- 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)
-toHeader _ = do
- empty
-
-
-- | Exception thrown when an integrity check fails
data HashMismatch = HashMismatch
{ expectedHash :: Crypto.Hash.Digest SHA256
@@ -431,6 +420,8 @@ instance Show HashMismatch where
<> "\n"
<> "↳ " <> show actualHash <> "\n"
+-- | Construct the file path corresponding to a local import. If the import is
+-- _relative_ then the resulting path is also relative.
localToPath :: MonadIO io => FilePrefix -> File -> io FilePath
localToPath prefix file_ = liftIO $ do
let File {..} = file_
@@ -445,11 +436,10 @@ localToPath prefix file_ = liftIO $ do
return "/"
Parent -> do
- pwd <- Directory.getCurrentDirectory
- return (FilePath.takeDirectory pwd)
+ return ".."
Here -> do
- Directory.getCurrentDirectory
+ return "."
let cs = map Text.unpack (file : components)
@@ -457,92 +447,300 @@ localToPath prefix file_ = liftIO $ do
return (foldr cons prefixPath cs)
--- | Parse an expression from a `Import` containing a Dhall program
-exprFromImport :: Import -> StateT (Status IO) IO Resolved
-exprFromImport here@(Import {..}) = do
- let ImportHashed {..} = importHashed
-
+-- | Given a `Local` import construct the corresponding unhashed `Chained`
+-- import (interpreting relative path as relative to the current directory).
+chainedFromLocalHere :: FilePrefix -> File -> ImportMode -> Chained
+chainedFromLocalHere prefix file mode = Chained $
+ Import (ImportHashed Nothing (Local prefix (canonicalize file))) mode
+
+-- | Adjust the import mode of a chained import
+chainedChangeMode :: ImportMode -> Chained -> Chained
+chainedChangeMode mode (Chained (Import importHashed _)) =
+ Chained (Import importHashed mode)
+
+-- Chain imports, also typecheck and normalize headers if applicable.
+chainImport :: Chained -> Import -> StateT Status IO Chained
+chainImport (Chained parent) child@(Import importHashed@(ImportHashed _ (Remote url)) _) = do
+ url' <- normalizeHeaders url
+ let child' = child { importHashed = importHashed { importType = Remote url' } }
+ return (Chained (canonicalize (parent <> child')))
+
+chainImport (Chained parent) child =
+ return (Chained (canonicalize (parent <> child)))
+
+-- | Load an import, resulting in a fully resolved, type-checked and normalised
+-- expression. @loadImport@ handles the 'hot' cache in @Status@ and defers to
+-- `loadImportWithSemanticCache` for imports that aren't in the @Status@ cache
+-- already.
+loadImport :: Chained -> StateT Status IO ImportSemantics
+loadImport import_ = do
Status {..} <- State.get
+ case Map.lookup import_ _cache of
+ Just importSemantics -> return importSemantics
+ Nothing -> do
+ importSemantics <- loadImportWithSemanticCache import_
+ zoom cache (State.modify (Map.insert import_ importSemantics))
+ return importSemantics
+
+-- | Load an import from the 'semantic cache'. Defers to
+-- `loadImportWithSemisemanticCache` for imports that aren't frozen (and
+-- therefore not cached semantically), as well as those that aren't cached yet.
+loadImportWithSemanticCache :: Chained -> StateT Status IO ImportSemantics
+loadImportWithSemanticCache
+ import_@(Chained (Import (ImportHashed Nothing _) _)) = do
+ loadImportWithSemisemanticCache import_
+
+loadImportWithSemanticCache
+ import_@(Chained (Import (ImportHashed (Just semanticHash) _) _)) = do
+ Status { .. } <- State.get
+ mCached <- liftIO $ fetchFromSemanticCache semanticHash
+
+ case mCached of
+ Just bytesStrict -> do
+ let actualHash = Crypto.Hash.hash bytesStrict
+ if semanticHash == actualHash
+ then return ()
+ else do
+ Status { _stack } <- State.get
+ throwMissingImport (Imported _stack (HashMismatch {expectedHash = semanticHash, ..}))
- result <- Maybe.runMaybeT $ do
- Just expectedHash <- return hash
- cacheFile <- getCacheFile expectedHash
- True <- liftIO (Directory.doesFileExist cacheFile)
-
- bytesStrict <- liftIO (Data.ByteString.readFile cacheFile)
-
- let actualHash = Crypto.Hash.hash bytesStrict
-
- if expectedHash == actualHash
- then return ()
- else throwMissingImport (Imported _stack (HashMismatch {..}))
-
- let bytesLazy = Data.ByteString.Lazy.fromStrict bytesStrict
-
- term <- Dhall.Core.throws (Codec.Serialise.deserialiseOrFail bytesLazy)
-
- Dhall.Core.throws (Dhall.Binary.decodeExpression term)
+ let bytesLazy = Data.ByteString.Lazy.fromStrict bytesStrict
+ term <- case Codec.Serialise.deserialiseOrFail bytesLazy of
+ Left err -> throwMissingImport (Imported _stack err)
+ Right t -> return t
+ importSemantics <- case Dhall.Binary.decodeExpression term of
+ Left err -> throwMissingImport (Imported _stack err)
+ Right sem -> return sem
- case result of
- Just resolvedExpression -> do
- let newImport = here
+ return (ImportSemantics {..})
- return (Resolved {..})
Nothing -> do
- exprFromUncachedImport here
+ ImportSemantics { importSemantics } <- loadImportWithSemisemanticCache import_
-{-| Save an expression to the specified `Import`
+ let variants = map (\version -> encodeExpression version (Dhall.Core.alphaNormalize importSemantics))
+ [ minBound .. maxBound ]
+ case Data.Foldable.find ((== semanticHash). Crypto.Hash.hash) variants of
+ Just bytes -> liftIO $ writeToSemanticCache semanticHash bytes
+ Nothing -> do
+ let expectedHash = semanticHash
+ Status { _standardVersion, _stack } <- State.get
+ let actualHash = hashExpression _standardVersion (Dhall.Core.alphaNormalize importSemantics)
+ throwMissingImport (Imported _stack (HashMismatch {..}))
+
+ return (ImportSemantics {..})
+
+-- Fetch encoded normal form from "semantic cache"
+fetchFromSemanticCache :: Crypto.Hash.Digest SHA256 -> IO (Maybe Data.ByteString.ByteString)
+fetchFromSemanticCache expectedHash = Maybe.runMaybeT $ do
+ cacheFile <- getCacheFile "dhall" expectedHash
+ True <- liftIO (Directory.doesFileExist cacheFile)
+ liftIO (Data.ByteString.readFile cacheFile)
+
+-- | Ensure that the given expression is present in the semantic cache. The
+-- given expression should be alpha-beta-normal.
+writeExpressionToSemanticCache :: Expr Src X -> IO ()
+writeExpressionToSemanticCache expression = writeToSemanticCache hash bytes
+ where
+ bytes = encodeExpression Dhall.Binary.defaultStandardVersion expression
+ hash = Crypto.Hash.hash bytes
- Currently this only works for cached imports and ignores other types of
- imports, but could conceivably work for uncached imports in the future
+writeToSemanticCache :: Crypto.Hash.Digest SHA256 -> Data.ByteString.ByteString -> IO ()
+writeToSemanticCache hash bytes = do
+ _ <- Maybe.runMaybeT $ do
+ cacheFile <- getCacheFile "dhall" hash
+ liftIO (Data.ByteString.writeFile cacheFile bytes)
+ return ()
- The main reason for this more general type is for symmetry with
- `exprFromImport` and to support doing more clever things in the future,
- like doing \"the right thing\" for uncached imports (i.e. exporting
- environment variables or creating files)
--}
-exprToImport :: Import -> Expr Src X -> StateT (Status IO) IO ()
-exprToImport here expression = do
+-- Check the "semi-semantic" disk cache, otherwise typecheck and normalise from
+-- scratch.
+loadImportWithSemisemanticCache
+ :: Chained -> StateT Status IO ImportSemantics
+loadImportWithSemisemanticCache (Chained (Import (ImportHashed _ importType) Code)) = do
+ text <- fetchFresh importType
Status {..} <- State.get
- let Import {..} = here
-
- let ImportHashed {..} = importHashed
+ path <- case importType of
+ Local prefix file -> liftIO $ do
+ path <- localToPath prefix file
+ absolutePath <- Directory.makeAbsolute path
+ return absolutePath
+ Remote url -> do
+ let urlText = Dhall.Pretty.Internal.pretty (url { headers = Nothing })
+ return (Text.unpack urlText)
+ Env env -> return $ Text.unpack env
+ Missing -> throwM (MissingImports [])
+
+ let parser = unParser $ do
+ Text.Parser.Token.whiteSpace
+ r <- Dhall.Parser.expr
+ Text.Parser.Combinators.eof
+ return r
+
+ parsedImport <- case Text.Megaparsec.parse parser path text of
+ Left errInfo -> do
+ throwMissingImport (Imported _stack (ParseError errInfo text))
+ Right expr -> return expr
+
+ resolvedExpr <- loadWith parsedImport -- we load imports recursively here
+
+ -- Check the semi-semantic cache. See
+ -- https://github.com/dhall-lang/dhall-haskell/issues/1098 for the reasoning
+ -- behind semi-semantic caching.
+ let semisemanticHash = computeSemisemanticHash resolvedExpr
+ mCached <- lift $ fetchFromSemisemanticCache semisemanticHash
+
+ importSemantics <- case mCached of
+ Just bytesStrict -> do
+ let bytesLazy = Data.ByteString.Lazy.fromStrict bytesStrict
+
+ term <- case Codec.Serialise.deserialiseOrFail bytesLazy of
+ Left err -> throwMissingImport (Imported _stack err)
+ Right t -> return t
+
+ importSemantics <- case Dhall.Binary.decodeExpression term of
+ Left err -> throwMissingImport (Imported _stack err)
+ Right sem -> return sem
+
+ return importSemantics
+ Nothing -> do
+ betaNormal <- case Dhall.TypeCheck.typeWith _startingContext resolvedExpr of
+ Left err -> throwMissingImport (Imported _stack err)
+ Right _ -> return (Dhall.Core.normalizeWith _normalizer resolvedExpr)
+
+ let bytes = encodeExpression _standardVersion betaNormal
+ lift $ writeToSemisemanticCache semisemanticHash bytes
+
+ return betaNormal
+
+ return (ImportSemantics {..})
+
+-- `as Text` imports aren't cached since they are well-typed and normal by
+-- construction
+loadImportWithSemisemanticCache (Chained (Import (ImportHashed _ importType) RawText)) = do
+ text <- fetchFresh importType
+
+ -- importSemantics is alpha-beta-normal by construction!
+ let importSemantics = TextLit (Chunks [] text)
+ return (ImportSemantics {..})
+
+-- `as Location` imports aren't cached since they are well-typed and normal by
+-- construction
+loadImportWithSemisemanticCache (Chained (Import (ImportHashed _ importType) Location)) = do
+ let locationType = Union $ Dhall.Map.fromList
+ [ ("Environment", Just Text)
+ , ("Remote", Just Text)
+ , ("Local", Just Text)
+ , ("Missing", Nothing)
+ ]
+
+ -- importSemantics is alpha-beta-normal by construction!
+ let importSemantics = case importType of
+ Missing -> Field locationType "Missing"
+ local@(Local _ _) ->
+ App (Field locationType "Local")
+ (TextLit (Chunks [] (Dhall.Pretty.Internal.pretty local)))
+ remote_@(Remote _) ->
+ App (Field locationType "Remote")
+ (TextLit (Chunks [] (Dhall.Pretty.Internal.pretty remote_)))
+ Env env ->
+ App (Field locationType "Environment")
+ (TextLit (Chunks [] (Dhall.Pretty.Internal.pretty env)))
+
+ return (ImportSemantics {..})
+
+-- The semi-semantic hash of an expression is computed from the fully resolved
+-- AST (without normalising or type-checking it first). See
+-- https://github.com/dhall-lang/dhall-haskell/issues/1098 for further
+-- discussion.
+computeSemisemanticHash :: Expr Src X -> Crypto.Hash.Digest Crypto.Hash.SHA256
+computeSemisemanticHash resolvedExpr =
+ hashExpression Dhall.Binary.defaultStandardVersion resolvedExpr
+
+-- Fetch encoded normal form from "semi-semantic cache"
+fetchFromSemisemanticCache :: Crypto.Hash.Digest SHA256 -> IO (Maybe Data.ByteString.ByteString)
+fetchFromSemisemanticCache semisemanticHash = Maybe.runMaybeT $ do
+ cacheFile <- getCacheFile "dhall-haskell" semisemanticHash
+ True <- liftIO (Directory.doesFileExist cacheFile)
+ liftIO (Data.ByteString.readFile cacheFile)
+
+writeToSemisemanticCache :: Crypto.Hash.Digest SHA256 -> Data.ByteString.ByteString -> IO ()
+writeToSemisemanticCache semisemanticHash bytes = do
_ <- Maybe.runMaybeT $ do
- Just expectedHash <- return hash
- cacheFile <- getCacheFile expectedHash
-
- _ <- Dhall.Core.throws (Dhall.TypeCheck.typeWith _startingContext expression)
-
- let normalizedExpression =
- Dhall.Core.alphaNormalize
- (Dhall.Core.normalizeWith
- _normalizer
- expression
- )
-
- let check version = do
- let bytes = encodeExpression version normalizedExpression
-
- let actualHash = Crypto.Hash.hash bytes
+ cacheFile <- getCacheFile "dhall-haskell" semisemanticHash
+ liftIO (Data.ByteString.writeFile cacheFile bytes)
+ return ()
- guard (expectedHash == actualHash)
+-- Fetch source code directly from disk/network
+fetchFresh :: ImportType -> StateT Status IO Text
+fetchFresh (Local prefix file) = do
+ Status { _stack } <- State.get
+ path <- liftIO $ localToPath prefix file