+\begin{frame}
+ \frametitle{Bidirectional type checking}
+ \[
+ \mysyn{data}\ \mytyc{List}\myappsp (\myb{A} : \mytyp) \mapsto \mydc{nil} \mydcsep \mydc{cons} \myappsp \myb{A}\myappsp (\mytyc{List}\myappsp\myb{A})
+ \]
+
+ With no type inference, we have explicit types for the constructors:
+ \[
+ \begin{array}{@{}l@{\ }l}
+ \mydc{nil} & : (\myb{A} : \mytyp) \myarr \mytyc{List}\myappsp\myb{A} \\
+ \mydc{cons} &: (\myb{A} : \mytyp) \myarr \myb{A} \myarr \mytyc{List}\myappsp\myb{A} \myarr \mytyc{List}\myappsp\myb{A}\\
+ \end{array}
+ \]
+ ...ugh:
+ \[
+ \mydc{cons}\myappsp \mynat\myappsp 1 \myappsp (\mydc{cons}\myappsp \mynat \myappsp 2 \myappsp (\mydc{cons}\myappsp \mynat \myappsp 3 \myappsp (\mydc{nil}\myappsp \mynat)))
+ \]
+ Instead, annotate terms and propagate the type:
+ \[
+ \mydc{cons}\myappsp 1 \myappsp (\mydc{cons}\myappsp 2 \myappsp (\mydc{cons} \myappsp 3 \myappsp \mydc{nil})) : \mytyc{List}\myappsp\mynat
+ \]
+ Conversely, when we use eliminators the type can be inferred.
+\end{frame}
+
+\begin{frame}
+ \frametitle{Bidirectional type checking}
+
+ This technique is known as \emph{bidirectional} type checking---some
+ terms get \emph{checked}, some terms \emph{infer} types.
+
+ Usually used for pre-defined types or core calculi, \mykant\ extends
+ to user-defined types.
+\end{frame}
+