`"Hello"+3`

valid.
+{{< /sidenote >}} such as:
+
+```Haskell
+if "Hello" then 0 else 1
+```
+
+For instance, a student may have a function `typecheck`, with the following
+signature (in Haskell):
+
+```Haskell
+typecheck :: Expr -> Either TypeError ExprType
+```
+
+The function will return an error if something goes wrong, or, if everything
+goes well, the type of the given expression. So far, so good.
+
+A student asked, however:
+
+> Now that I ran type checking on my program, surely I don't need to include errors
+in my {{< sidenote "right" "valuation-function-note" "valuation function!" >}}
+I'm using "valuation function" here in the context of
+denotational semantics.
+In short, a
+valuation function
+takes an expression and assigns to it some
+representation of its meaning. For a language of arithmetic expression, the
+"meaning" of an expression is just a number (the result of simplifying the expression).
+For a language of booleans, `and`

, and `or`

, the "meaning" is a boolean
+for the same reason. Since an expression in the language can be ill-formed (like
+`list(5)`

in Python), the "meaning" (`SafeExpr`

is that of
+a
+Generalized Algebraic Data Type,
+or GADT for short. This is what allows each of our constructors to produce
+values of a different type: `IntLiteral`

builds `SafeExpr IntType`

,
+while `BoolLiteral`

builds `SafeExpr BoolType`

.
+{{}} which we will discuss below:
+
+{{< codelines "Idris" "typesafe-interpreter/TypesafeIntr.idr" 23 27 >}}
+
+The first line of the above snippet says, "`SafeExpr` is a type constructor
+that requires a value of type `ExprType`". For example, we can have
+`SafeExpr IntType`, or `SafeExpr BoolType`. Next, we have to define constructors
+for `SafeExpr`. One such constructor is `IntLiteral`, which takes a value of
+type `Int` (which represents the value of the integer literal), and builds
+a value of `SafeExpr IntType`, that is, an expression that __we know evaluates
+to an integer__.
+
+The same is the case for `BoolLiteral` and `StringLiteral`, only they build
+values of type `SafeExpr BoolType` and `SafeExpr StringType`, respectively.
+
+The more complicated case is that of `BinOperation`. Put simply, it takes
+a binary function of type `a->b->c` (kind of), two `SafeExpr`s producing `a` and `b`,
+and combines the values of those expressions using the function to generate
+a value of type `c`. Since the whole expression returns `c`, `BinOperation`
+builds a value of type `SafeExpr c`.
+
+That's almost it. Except, what's up with `repr`? We need it because `SafeExpr`
+is parameterized by a __value__ of type `ExprType`. Thus, `a`, `b`, and `c` are
+all values in the definition of `BinOperation`. However, in a function
+`input->output`, both `input` and `output` have to be __types__, not values.
+Thus, we define a function `repr` which converts values such as `IntType` into
+the actual type that `eval` would yield when running our expression:
+
+{{< codelines "Idris" "typesafe-interpreter/TypesafeIntr.idr" 6 9 >}}
+
+The power of dependent types allows us to run `repr` inside the type
+of `BinOp` to compute the type of the function it must accept.