Add Note constructor

This commit is contained in:
Gabriel Gonzalez 2016-10-29 21:48:18 -07:00
parent fa6619d892
commit 2909f8871b
5 changed files with 180 additions and 107 deletions

View File

@ -318,6 +318,7 @@ import Data.ByteString.Lazy (ByteString)
import Data.Text.Lazy (Text)
import Data.Vector (Vector)
import Dhall.Core (Expr(..))
import Dhall.Parser (Src)
import Dhall.TypeCheck (X)
import GHC.Generics
import Numeric.Natural (Natural)
@ -386,8 +387,8 @@ input (Type {..}) bytes = do
> input :: Type a -> Text -> IO a
-}
data Type a = Type
{ extract :: Expr X -> Maybe a
, expected :: Expr X
{ extract :: Expr X X -> Maybe a
, expected :: Expr Src X
}
deriving (Functor)

View File

@ -51,6 +51,7 @@ module Dhall.Core (
#else
import Control.Applicative (Applicative(..), (<$>))
#endif
import Data.Bifunctor (Bifunctor(..))
import Data.Foldable
import Data.Map (Map)
import Data.Monoid ((<>))
@ -157,38 +158,38 @@ instance Buildable Var where
build = buildVar
-- | Syntax tree for expressions
data Expr a
data Expr s a
-- | > Const c ~ c
= Const Const
-- | > Var (V x 0) ~ x
-- > Var (V x n) ~ x@n
| Var Var
-- | > Lam x A b ~ λ(x : A) -> b
| Lam Text (Expr a) (Expr a)
| Lam Text (Expr s a) (Expr s a)
-- | > Pi "_" A B ~ A -> B
-- > Pi x A B ~ ∀(x : A) -> B
| Pi Text (Expr a) (Expr a)
| Pi Text (Expr s a) (Expr s a)
-- | > App f a ~ f a
| App (Expr a) (Expr a)
| App (Expr s a) (Expr s a)
-- | > Let x Nothing r e ~ let x = r in e
-- > Let x (Just t) r e ~ let x : t = r in e
| Let Text (Maybe (Expr a)) (Expr a) (Expr a)
| Let Text (Maybe (Expr s a)) (Expr s a) (Expr s a)
-- | > Annot x t ~ x : t
| Annot (Expr a) (Expr a)
| Annot (Expr s a) (Expr s a)
-- | > Bool ~ Bool
| Bool
-- | > BoolLit b ~ b
| BoolLit Bool
-- | > BoolAnd x y ~ x && y
| BoolAnd (Expr a) (Expr a)
| BoolAnd (Expr s a) (Expr s a)
-- | > BoolOr x y ~ x || y
| BoolOr (Expr a) (Expr a)
| BoolOr (Expr s a) (Expr s a)
-- | > BoolEQ x y ~ x == y
| BoolEQ (Expr a) (Expr a)
| BoolEQ (Expr s a) (Expr s a)
-- | > BoolNE x y ~ x /= y
| BoolNE (Expr a) (Expr a)
| BoolNE (Expr s a) (Expr s a)
-- | > BoolIf x y z ~ if x then y else z
| BoolIf (Expr a) (Expr a) (Expr a)
| BoolIf (Expr s a) (Expr s a) (Expr s a)
-- | > Natural ~ Natural
| Natural
-- | > NaturalLit n ~ +n
@ -204,9 +205,9 @@ data Expr a
-- | > NaturalOdd ~ Natural/odd
| NaturalOdd
-- | > NaturalPlus x y ~ x + y
| NaturalPlus (Expr a) (Expr a)
| NaturalPlus (Expr s a) (Expr s a)
-- | > NaturalTimes x y ~ x * y
| NaturalTimes (Expr a) (Expr a)
| NaturalTimes (Expr s a) (Expr s a)
-- | > Integer ~ Integer
| Integer
-- | > IntegerLit n ~ n
@ -220,11 +221,11 @@ data Expr a
-- | > TextLit t ~ t
| TextLit Builder
-- | > TextAppend x y ~ x ++ y
| TextAppend (Expr a) (Expr a)
| TextAppend (Expr s a) (Expr s a)
-- | > List ~ List
| List
-- | > ListLit t [x, y, z] ~ [x, y, z] : List t
| ListLit (Expr a) (Vector (Expr a))
| ListLit (Expr s a) (Vector (Expr s a))
-- | > ListBuild ~ List/build
| ListBuild
-- | > ListFold ~ List/fold
@ -243,33 +244,35 @@ data Expr a
| Maybe
-- | > MaybeLit t [e] ~ [e] : Maybe t
-- > MaybeLit t [] ~ [] : Maybe t
| MaybeLit (Expr a) (Vector (Expr a))
| MaybeLit (Expr s a) (Vector (Expr s a))
-- | > MaybeFold ~ Maybe/fold
| MaybeFold
-- | > Record [(k1, t1), (k2, t2)] ~ { k1 : t1, k2 : t1 }
| Record (Map Text (Expr a))
| Record (Map Text (Expr s a))
-- | > RecordLit [(k1, v1), (k2, v2)] ~ { k1 = v1, k2 = v2 }
| RecordLit (Map Text (Expr a))
| RecordLit (Map Text (Expr s a))
-- | > Union [(k1, t1), (k2, t2)] ~ < k1 : t1, k2 : t2 >
| Union (Map Text (Expr a))
| Union (Map Text (Expr s a))
-- | > UnionLit (k1, v1) [(k2, t2), (k3, t3)] ~ < k1 = t1, k2 : t2, k3 : t3 >
| UnionLit Text (Expr a) (Map Text (Expr a))
| UnionLit Text (Expr s a) (Map Text (Expr s a))
-- | > Merge x y ~ x ∧ y
| Merge (Expr a) (Expr a)
| Merge (Expr s a) (Expr s a)
-- | > Apply x y t ~ apply x y : t
| Apply (Expr a) (Expr a) (Expr a)
| Apply (Expr s a) (Expr s a) (Expr s a)
-- | > Field e x ~ e.x
| Field (Expr a) Text
| Field (Expr s a) Text
-- | > Note s x ~ e
| Note s (Expr s a)
-- | > Embed path ~ path
| Embed a
deriving (Functor, Foldable, Traversable, Show)
instance Applicative Expr where
instance Applicative (Expr s) where
pure = Embed
(<*>) = Control.Monad.ap
instance Monad Expr where
instance Monad (Expr s) where
return = pure
Const c >>= _ = Const c
@ -321,9 +324,65 @@ instance Monad Expr where
Merge x y >>= k = Merge (x >>= k) (y >>= k)
Apply x y t >>= k = Apply (x >>= k) (y >>= k) (t >>= k)
Field r x >>= k = Field (r >>= k) x
Note a b >>= k = Note a (b >>= k)
Embed r >>= k = k r
instance IsString (Expr a)
instance Bifunctor Expr where
first _ (Const a ) = Const a
first _ (Var a ) = Var a
first k (Lam a b c ) = Lam a (first k b) (first k c)
first k (Pi a b c ) = Pi a (first k b) (first k c)
first k (App a b ) = App (first k a) (first k b)
first k (Let a b c d ) = Let a (fmap (first k) b) (first k c) (first k d)
first k (Annot a b ) = Annot (first k a) (first k b)
first _ Bool = Bool
first _ (BoolLit a ) = BoolLit a
first k (BoolAnd a b ) = BoolAnd (first k a) (first k b)
first k (BoolOr a b ) = BoolOr (first k a) (first k b)
first k (BoolEQ a b ) = BoolEQ (first k a) (first k b)
first k (BoolNE a b ) = BoolNE (first k a) (first k b)
first k (BoolIf a b c ) = BoolIf (first k a) (first k b) (first k c)
first _ Natural = Natural
first _ (NaturalLit a ) = NaturalLit a
first _ NaturalFold = NaturalFold
first _ NaturalBuild = NaturalBuild
first _ NaturalIsZero = NaturalIsZero
first _ NaturalEven = NaturalEven
first _ NaturalOdd = NaturalOdd
first k (NaturalPlus a b ) = NaturalPlus (first k a) (first k b)
first k (NaturalTimes a b) = NaturalTimes (first k a) (first k b)
first _ Integer = Integer
first _ (IntegerLit a ) = IntegerLit a
first _ Double = Double
first _ (DoubleLit a ) = DoubleLit a
first _ Text = Text
first _ (TextLit a ) = TextLit a
first k (TextAppend a b ) = TextAppend (first k a) (first k b)
first _ List = List
first k (ListLit a b ) = ListLit (first k a) (fmap (first k) b)
first _ ListBuild = ListBuild
first _ ListFold = ListFold
first _ ListLength = ListLength
first _ ListHead = ListHead
first _ ListLast = ListLast
first _ ListIndexed = ListIndexed
first _ ListReverse = ListReverse
first _ Maybe = Maybe
first k (MaybeLit a b ) = MaybeLit (first k a) (fmap (first k) b)
first _ MaybeFold = MaybeFold
first k (Record a ) = Record (fmap (first k) a)
first k (RecordLit a ) = RecordLit (fmap (first k) a)
first k (Union a ) = Union (fmap (first k) a)
first k (UnionLit a b c ) = UnionLit a (first k b) (fmap (first k) c)
first k (Merge a b ) = Merge (first k a) (first k b)
first k (Apply a b c ) = Apply (first k a) (first k b) (first k c)
first k (Field a b ) = Field (first k a) b
first k (Note a b ) = Note (k a) (first k b)
first _ (Embed a ) = Embed a
second = fmap
instance IsString (Expr s a)
where
fromString str = Var (fromString str)
@ -364,14 +423,14 @@ buildText :: Builder -> Builder
buildText a = build (show a)
-- | Builder corresponding to the @Expr0@ parser in "Dhall.Parser"
buildExpr0 :: Buildable a => Expr a -> Builder
buildExpr0 :: Buildable a => Expr s a -> Builder
buildExpr0 (Annot a b) =
buildExpr1 a <> " : " <> buildExpr0 b
buildExpr0 a =
buildExpr1 a
-- | Builder corresponding to the @Expr1@ parser in "Dhall.Parser"
buildExpr1 :: Buildable a => Expr a -> Builder
buildExpr1 :: Buildable a => Expr s a -> Builder
buildExpr1 (Lam a b c) =
"λ("
<> buildLabel a
@ -437,32 +496,32 @@ buildExpr1 a =
buildExpr2 a
-- | Builder corresponding to the @Expr2@ parser in "Dhall.Parser"
buildExpr2 :: Buildable a => Expr a -> Builder
buildExpr2 :: Buildable a => Expr s a -> Builder
buildExpr2 (BoolEQ a b) = buildExpr2 a <> " == " <> buildExpr2 b
buildExpr2 (BoolNE a b) = buildExpr2 a <> " /= " <> buildExpr2 b
buildExpr2 a = buildExpr3 a
-- | Builder corresponding to the @Expr3@ parser in "Dhall.Parser"
buildExpr3 :: Buildable a => Expr a -> Builder
buildExpr3 :: Buildable a => Expr s a -> Builder
buildExpr3 (BoolOr a b) = buildExpr3 a <> " || " <> buildExpr3 b
buildExpr3 (NaturalPlus a b) = buildExpr3 a <> " + " <> buildExpr3 b
buildExpr3 (TextAppend a b) = buildExpr3 a <> " ++ " <> buildExpr3 b
buildExpr3 a = buildExpr4 a
-- | Builder corresponding to the @Expr4@ parser in "Dhall.Parser"
buildExpr4 :: Buildable a => Expr a -> Builder
buildExpr4 :: Buildable a => Expr s a -> Builder
buildExpr4 (BoolAnd a b) = buildExpr4 a <> " && " <> buildExpr4 b
buildExpr4 (NaturalTimes a b) = buildExpr4 a <> " * " <> buildExpr4 b
buildExpr4 (Merge a b) = buildExpr4 a <> "" <> buildExpr4 b
buildExpr4 a = buildExpr5 a
-- | Builder corresponding to the @Expr5@ parser in "Dhall.Parser"
buildExpr5 :: Buildable a => Expr a -> Builder
buildExpr5 :: Buildable a => Expr s a -> Builder
buildExpr5 (App a b) = buildExpr5 a <> " " <> buildExpr6 b
buildExpr5 a = buildExpr6 a
-- | Builder corresponding to the @Expr6@ parser in "Dhall.Parser"
buildExpr6 :: Buildable a => Expr a -> Builder
buildExpr6 :: Buildable a => Expr s a -> Builder
buildExpr6 (Var a) =
buildVar a
buildExpr6 (Const k) =
@ -545,54 +604,54 @@ buildVar (V x 0) = buildLabel x
buildVar (V x n) = buildLabel x <> "@" <> buildNumber n
-- | Builder corresponding to the @Elems@ parser in "Dhall.Parser"
buildElems :: Buildable a => [Expr a] -> Builder
buildElems :: Buildable a => [Expr s a] -> Builder
buildElems [] = ""
buildElems [a] = buildExpr0 a
buildElems (a:bs) = buildExpr0 a <> ", " <> buildElems bs
-- | Builder corresponding to the @RecordLit@ parser in "Dhall.Parser"
buildRecordLit :: Buildable a => Map Text (Expr a) -> Builder
buildRecordLit :: Buildable a => Map Text (Expr s a) -> Builder
buildRecordLit a | Data.Map.null a =
"{=}"
buildRecordLit a =
"{ " <> buildFieldValues (Data.Map.toList a) <> " }"
-- | Builder corresponding to the @FieldValues@ parser in "Dhall.Parser"
buildFieldValues :: Buildable a => [(Text, Expr a)] -> Builder
buildFieldValues :: Buildable a => [(Text, Expr s a)] -> Builder
buildFieldValues [] = ""
buildFieldValues [a] = buildFieldValue a
buildFieldValues (a:bs) = buildFieldValue a <> ", " <> buildFieldValues bs
-- | Builder corresponding to the @FieldValue@ parser in "Dhall.Parser"
buildFieldValue :: Buildable a => (Text, Expr a) -> Builder
buildFieldValue :: Buildable a => (Text, Expr s a) -> Builder
buildFieldValue (a, b) = buildLabel a <> " = " <> buildExpr0 b
-- | Builder corresponding to the @Record@ parser in "Dhall.Parser"
buildRecord :: Buildable a => Map Text (Expr a) -> Builder
buildRecord :: Buildable a => Map Text (Expr s a) -> Builder
buildRecord a | Data.Map.null a =
"{}"
buildRecord a =
"{ " <> buildFieldTypes (Data.Map.toList a) <> " }"
-- | Builder corresponding to the @FieldTypes@ parser in "Dhall.Parser"
buildFieldTypes :: Buildable a => [(Text, Expr a)] -> Builder
buildFieldTypes :: Buildable a => [(Text, Expr s a)] -> Builder
buildFieldTypes [] = ""
buildFieldTypes [a] = buildFieldType a
buildFieldTypes (a:bs) = buildFieldType a <> ", " <> buildFieldTypes bs
-- | Builder corresponding to the @FieldType@ parser in "Dhall.Parser"
buildFieldType :: Buildable a => (Text, Expr a) -> Builder
buildFieldType :: Buildable a => (Text, Expr s a) -> Builder
buildFieldType (a, b) = buildLabel a <> " : " <> buildExpr0 b
-- | Builder corresponding to the @Union@ parser in "Dhall.Parser"
buildUnion :: Buildable a => Map Text (Expr a) -> Builder
buildUnion :: Buildable a => Map Text (Expr s a) -> Builder
buildUnion a | Data.Map.null a =
"<>"
buildUnion a =
"< " <> buildAlternativeTypes (Data.Map.toList a) <> " >"
-- | Builder corresponding to the @AlternativeTypes@ parser in "Dhall.Parser"
buildAlternativeTypes :: Buildable a => [(Text, Expr a)] -> Builder
buildAlternativeTypes :: Buildable a => [(Text, Expr s a)] -> Builder
buildAlternativeTypes [] =
""
buildAlternativeTypes [a] =
@ -601,11 +660,11 @@ buildAlternativeTypes (a:bs) =
buildAlternativeType a <> " | " <> buildAlternativeTypes bs
-- | Builder corresponding to the @AlternativeType@ parser in "Dhall.Parser"
buildAlternativeType :: Buildable a => (Text, Expr a) -> Builder
buildAlternativeType :: Buildable a => (Text, Expr s a) -> Builder
buildAlternativeType (a, b) = buildLabel a <> " : " <> buildExpr0 b
-- | Builder corresponding to the @UnionLit@ parser in "Dhall.Parser"
buildUnionLit :: Buildable a => Text -> Expr a -> Map Text (Expr a) -> Builder
buildUnionLit :: Buildable a => Text -> Expr s a -> Map Text (Expr s a) -> Builder
buildUnionLit a b c
| Data.Map.null c =
"< "
@ -623,7 +682,7 @@ buildUnionLit a b c
<> " >"
-- | Generates a syntactically valid Dhall program
instance Buildable a => Buildable (Expr a)
instance Buildable a => Buildable (Expr s a)
where
build = buildExpr0
@ -688,7 +747,7 @@ instance Buildable a => Buildable (Expr a)
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 a -> Expr a
shift :: Integer -> Var -> Expr s a -> Expr t a
shift _ _ (Const a) = Const a
shift d (V x n) (Var (V x' n')) = Var (V x' n'')
where
@ -812,6 +871,9 @@ shift d v (Apply a b c) = Apply a' b' c'
shift d v (Field a b) = Field a' b
where
a' = shift d v a
shift d v (Note _ b) = b'
where
b' = shift d v b
-- The Dhall compiler enforces that all embedded values are closed expressions
-- and `shift` does nothing to a closed expression
shift _ _ (Embed p) = Embed p
@ -820,7 +882,7 @@ shift _ _ (Embed p) = Embed p
> subst x C B ~ B[x := C]
-}
subst :: Var -> Expr a -> Expr a -> Expr a
subst :: Var -> Expr s a -> Expr t a -> Expr s a
subst _ _ (Const a) = Const a
subst (V x n) e (Lam y _A b) = Lam y _A' b'
where
@ -931,6 +993,9 @@ subst x e (Apply a b c) = Apply a' b' c'
subst x e (Field a b) = Field a' b
where
a' = subst x e a
subst x e (Note _ b) = b'
where
b' = subst x e b
-- The Dhall compiler enforces that all embedded values are closed expressions
-- and `subst` does nothing to a closed expression
subst _ _ (Embed p) = Embed p
@ -944,7 +1009,7 @@ subst _ _ (Embed p) = Embed p
However, `normalize` will not fail if the expression is ill-typed and will
leave ill-typed sub-expressions unevaluated.
-}
normalize :: Expr a -> Expr a
normalize :: Expr s a -> Expr t a
normalize e = case e of
Const k -> Const k
Var v -> Var v
@ -1184,7 +1249,7 @@ normalize e = case e of
RecordLit kvsX ->
case y of
RecordLit kvsY ->
RecordLit (Data.Map.union kvsX kvsY)
RecordLit (fmap normalize (Data.Map.union kvsX kvsY))
_ -> Merge x' y'
_ -> Merge x' y'
where
@ -1211,6 +1276,7 @@ normalize e = case e of
Just v -> normalize v
Nothing -> Field (RecordLit (fmap normalize kvs)) x
r' -> Field r' x
Note _ e' -> normalize e'
Embed a -> Embed a
where
internalError :: forall b . b
@ -1230,12 +1296,12 @@ $text
```
|])
where
-- This is to avoid a `Show` constraint on the @a@ in the type of
-- This is to avoid a `Show` constraint on the @a@ and @s@ in the type of
-- `normalize`. In theory, this might change a failing repro case into
-- a successful one, but the risk of that is low enough to not warrant
-- the `Show` constraint. I care more about proving at the type level
-- that the @a@ parameter is never used
e' = fmap (\_ -> ()) e
-- that the @a@ and @s@ type parameters are never used
e' = bimap (\_ -> ()) (\_ -> ()) e
text = "normalize (" <> Data.Text.pack (show e') <> ")"

View File

@ -96,6 +96,7 @@ import Filesystem as Filesystem
import Lens.Micro (Lens')
import Lens.Micro.Mtl (zoom)
import Dhall.Core (Expr, Path(..))
import Dhall.Parser (Src)
import Dhall.TypeCheck (X(..))
import Network.HTTP.Client (Manager)
import Prelude hiding (FilePath)
@ -182,7 +183,7 @@ instance Show e => Show (Imported e) where
data Status = Status
{ _stack :: [Path]
, _cache :: Map Path (Expr X)
, _cache :: Map Path (Expr Src X)
, _manager :: Maybe Manager
}
@ -192,7 +193,7 @@ canonicalizeAll = map canonicalize . List.tails
stack :: Lens' Status [Path]
stack k s = fmap (\x -> s { _stack = x }) (k (_stack s))
cache :: Lens' Status (Map Path (Expr X))
cache :: Lens' Status (Map Path (Expr Src X))
cache k s = fmap (\x -> s { _cache = x }) (k (_cache s))
manager :: Lens' Status (Maybe Manager)
@ -299,7 +300,7 @@ clean = strip . Filesystem.collapse
This also returns the true final path (i.e. explicit "/@" at the end for
directories)
-}
loadDynamic :: Path -> StateT Status IO (Expr Path)
loadDynamic :: Path -> StateT Status IO (Expr Src Path)
loadDynamic p = do
paths <- zoom stack State.get
@ -357,7 +358,7 @@ loadDynamic p = do
Right expr -> return expr
-- | Load a `Path` as a \"static\" expression (with all imports resolved)
loadStatic :: Path -> StateT Status IO (Expr X)
loadStatic :: Path -> StateT Status IO (Expr Src X)
loadStatic path = do
paths <- zoom stack State.get
@ -421,9 +422,9 @@ loadStatic path = do
load
:: Maybe Path
-- ^ Starting path
-> Expr Path
-> Expr Src Path
-- ^ Expression to resolve
-> IO (Expr X)
-> IO (Expr Src X)
load here expr =
State.evalStateT (fmap join (traverse loadStatic expr)) status
where

View File

@ -10,6 +10,7 @@ module Dhall.Parser (
exprFromBytes
-- * Types
, Src(..)
, ParseError(..)
) where
@ -349,6 +350,8 @@ Import
{ URL $1 }
{
data Src = Src deriving (Typeable)
parseError :: Token -> Alex a
parseError token = do
(AlexPn _ line column, _, bytes, _) <- Dhall.Lexer.alexGetInput
@ -388,7 +391,7 @@ instance Exception ParseError
{-| Parse an expression from a `ByteString` containing a UTF8-encoded Dhall
program
-}
exprFromBytes :: ByteString -> Either ParseError (Expr Path)
exprFromBytes :: ByteString -> Either ParseError (Expr Src Path)
exprFromBytes bytes = case Dhall.Lexer.runAlex bytes expr of
Left str -> Left (ParseError (Data.Text.Lazy.pack str))
Right e -> Right e

View File

@ -16,7 +16,6 @@ module Dhall.TypeCheck (
) where
import Control.Exception (Exception)
import Control.Monad.Trans.State.Strict (State)
import Data.Foldable (forM_)
import Data.Monoid ((<>))
import Data.Set (Set)
@ -38,7 +37,7 @@ import qualified Dhall.Context
import qualified Dhall.Core
import qualified NeatInterpolation
axiom :: Const -> Either TypeError Const
axiom :: Const -> Either (TypeError s) Const
axiom Type = return Kind
axiom Kind = Left (TypeError Dhall.Context.empty (Const Kind) (Untyped Kind))
@ -59,13 +58,12 @@ match (V xL nL) (V xR nR) ((xL', xR'):xs) =
nL' = if xL == xL' then nL - 1 else nL
nR' = if xR == xR' then nR - 1 else nR
propEqual :: Expr X -> Expr X -> Bool
propEqual :: Expr s X -> Expr t X -> Bool
propEqual eL0 eR0 =
State.evalState
(go (Dhall.Core.normalize eL0) (Dhall.Core.normalize eR0))
[]
where
go :: Expr X -> Expr X -> State [(Text, Text)] Bool
go (Const Type) (Const Type) = return True
go (Const Kind) (Const Kind) = return True
go (Var vL) (Var vR) = do
@ -120,7 +118,7 @@ propEqual eL0 eR0 =
is not necessary for just type-checking. If you actually care about the
returned type then you may want to `normalize` it afterwards.
-}
typeWith :: Context (Expr X) -> Expr X -> Either TypeError (Expr X)
typeWith :: Context (Expr s X) -> Expr s X -> Either (TypeError s) (Expr s X)
typeWith _ (Const c ) = do
fmap Const (axiom c)
typeWith ctx e@(Var (V x n) ) = do
@ -477,6 +475,10 @@ typeWith ctx e@(Field r x ) = do
Just t' -> return t'
Nothing -> Left (TypeError ctx e (MissingField x t))
_ -> Left (TypeError ctx e (NotARecord x r t))
typeWith ctx (Note s e' ) = case typeWith ctx e' of
Left (TypeError ctx' (Note _ e'') m) -> Left (TypeError ctx' (Note s e'') m)
Left (TypeError ctx' e'' m) -> Left (TypeError ctx' (Note s e'') m)
Right r -> Right r
typeWith _ (Embed p ) = do
absurd p
@ -484,7 +486,7 @@ typeWith _ (Embed p ) = do
expression must be closed (i.e. no free variables), otherwise type-checking
will fail.
-}
typeOf :: Expr X -> Either TypeError (Expr X)
typeOf :: Expr s X -> Either (TypeError s) (Expr s X)
typeOf = typeWith Dhall.Context.empty
-- | Like `Data.Void.Void`, except with a shorter inferred type
@ -497,46 +499,46 @@ instance Buildable X where
build = absurd
-- | The specific type error
data TypeMessage
data TypeMessage s
= UnboundVariable
| InvalidInputType (Expr X)
| InvalidOutputType (Expr X)
| NotAFunction (Expr X)
| TypeMismatch (Expr X) (Expr X)
| AnnotMismatch (Expr X) (Expr X) (Expr X)
| InvalidInputType (Expr s X)
| InvalidOutputType (Expr s X)
| NotAFunction (Expr s X)
| TypeMismatch (Expr s X) (Expr s X)
| AnnotMismatch (Expr s X) (Expr s X) (Expr s X)
| Untyped Const
| InvalidListElement Int Int (Expr X) (Expr X) (Expr X)
| InvalidListType Bool (Expr X)
| InvalidMaybeElement (Expr X) (Expr X) (Expr X)
| InvalidListElement Int Int (Expr s X) (Expr s X) (Expr s X)
| InvalidListType Bool (Expr s X)
| InvalidMaybeElement (Expr s X) (Expr s X) (Expr s X)
| InvalidMaybeLiteral Int
| InvalidMaybeType (Expr X)
| InvalidPredicate (Expr X) (Expr X)
| IfBranchMismatch (Expr X) (Expr X) (Expr X) (Expr X)
| InvalidFieldType Text (Expr X)
| InvalidAlternativeType Text (Expr X)
| InvalidMaybeType (Expr s X)
| InvalidPredicate (Expr s X) (Expr s X)
| IfBranchMismatch (Expr s X) (Expr s X) (Expr s X) (Expr s X)
| InvalidFieldType Text (Expr s X)
| InvalidAlternativeType Text (Expr s X)
| DuplicateField Text
| MustMergeARecord (Expr X) (Expr X)
| MustMergeARecord (Expr s X) (Expr s X)
| FieldCollision (Set Text)
| MustApplyARecord (Expr X) (Expr X)
| MustApplyToUnion (Expr X)
| MustApplyARecord (Expr s X) (Expr s X)
| MustApplyToUnion (Expr s X)
| UnusedHandler (Set Text)
| MissingHandler (Set Text)
| HandlerInputTypeMismatch Text (Expr X) (Expr X)
| HandlerOutputTypeMismatch Text (Expr X) (Expr X)
| HandlerNotAFunction Text (Expr X)
| NotARecord Text (Expr X) (Expr X)
| MissingField Text (Expr X)
| CantAnd Bool (Expr X) (Expr X)
| CantOr Bool (Expr X) (Expr X)
| CantEQ Bool (Expr X) (Expr X)
| CantNE Bool (Expr X) (Expr X)
| CantTextAppend Bool (Expr X) (Expr X)
| CantAdd Bool (Expr X) (Expr X)
| CantMultiply Bool (Expr X) (Expr X)
| NoDependentTypes (Expr X) (Expr X)
| HandlerInputTypeMismatch Text (Expr s X) (Expr s X)
| HandlerOutputTypeMismatch Text (Expr s X) (Expr s X)
| HandlerNotAFunction Text (Expr s X)
| NotARecord Text (Expr s X) (Expr s X)
| MissingField Text (Expr s X)
| CantAnd Bool (Expr s X) (Expr s X)
| CantOr Bool (Expr s X) (Expr s X)
| CantEQ Bool (Expr s X) (Expr s X)
| CantNE Bool (Expr s X) (Expr s X)
| CantTextAppend Bool (Expr s X) (Expr s X)
| CantAdd Bool (Expr s X) (Expr s X)
| CantMultiply Bool (Expr s X) (Expr s X)
| NoDependentTypes (Expr s X) (Expr s X)
deriving (Show)
instance Buildable TypeMessage where
instance Buildable (TypeMessage s) where
build UnboundVariable =
Builder.fromText [NeatInterpolation.text|
Error: Unbound variable
@ -1335,7 +1337,7 @@ Your function type is invalid because the input is a term of type:
indent :: Data.Text.Text -> Data.Text.Text
indent = Data.Text.unlines . fmap (" " <>) . Data.Text.lines
buildBooleanOperator :: Text -> Bool -> Expr X -> Expr X -> Builder
buildBooleanOperator :: Text -> Bool -> Expr s X -> Expr s X -> Builder
buildBooleanOperator operator b expr0 expr1 =
Builder.fromText [NeatInterpolation.text|
Error: Cannot use `($txt2)` on a value that's not a `Bool`
@ -1358,7 +1360,7 @@ You provided this argument:
then [NeatInterpolation.text|$txt0 $txt2 ...|]
else [NeatInterpolation.text|... $txt2 $txt0|]
buildNaturalOperator :: Text -> Bool -> Expr X -> Expr X -> Builder
buildNaturalOperator :: Text -> Bool -> Expr s X -> Expr s X -> Builder
buildNaturalOperator operator b expr0 expr1 =
Builder.fromText [NeatInterpolation.text|
Error: Cannot use `($txt2)` on a value that's not a `Natural`
@ -1402,18 +1404,18 @@ Example:
_ -> mempty
-- | A structured type error that includes context
data TypeError = TypeError
{ context :: Context (Expr X)
, current :: Expr X
, typeMessage :: TypeMessage
data TypeError s = TypeError
{ context :: Context (Expr s X)
, current :: Expr s X
, typeMessage :: TypeMessage s
} deriving (Typeable)
instance Show TypeError where
instance Show (TypeError s) where
show = Text.unpack . Dhall.Core.pretty
instance Exception TypeError
instance Typeable s => Exception (TypeError s)
instance Buildable TypeError where
instance Buildable (TypeError s) where
build (TypeError ctx expr msg)
= "\n"
<> ( if Text.null (Builder.toLazyText (buildContext ctx))