2024-01-11 13:38:32 +01:00
|
|
|
|
\section{Partiality in Type Theory}
|
2024-01-12 17:36:59 +01:00
|
|
|
|
|
|
|
|
|
% TODO
|
|
|
|
|
% - remove vskips and use begin{listing}
|
|
|
|
|
% - add colist definition
|
|
|
|
|
|
2024-01-03 19:51:04 +01:00
|
|
|
|
\begin{frame}[t, fragile]{Partiality in Haskell}{}
|
2024-01-12 17:36:59 +01:00
|
|
|
|
Haskell allows users to define arbitrary partial functions
|
2024-01-11 13:38:32 +01:00
|
|
|
|
\begin{itemize}
|
2024-01-12 17:36:59 +01:00
|
|
|
|
\item<1-> Some can be spotted easily by their definition:
|
|
|
|
|
\vskip 0.5cm
|
|
|
|
|
\begin{minted}{haskell}
|
2024-01-03 19:51:04 +01:00
|
|
|
|
head :: [a] -> a
|
2024-01-11 13:38:32 +01:00
|
|
|
|
head [] = error "empty list"
|
2024-01-03 19:51:04 +01:00
|
|
|
|
head (x:xs) = x
|
2024-01-11 13:38:32 +01:00
|
|
|
|
\end{minted}
|
2024-01-12 17:36:59 +01:00
|
|
|
|
\mycallout<2->{22, 1.5}{
|
2024-01-06 15:04:04 +01:00
|
|
|
|
ghci> head []\\
|
|
|
|
|
*** Exception: empty list\\
|
|
|
|
|
CallStack (from HasCallStack):\\
|
|
|
|
|
error, called at example.hs:2:9 in main:Main
|
|
|
|
|
}
|
2024-01-11 13:38:32 +01:00
|
|
|
|
\item<3->
|
2024-01-06 15:04:04 +01:00
|
|
|
|
others might be more subtle:
|
2024-01-12 17:36:59 +01:00
|
|
|
|
\vskip 0.5cm
|
|
|
|
|
\begin{minted}{haskell}
|
2024-01-11 13:38:32 +01:00
|
|
|
|
reverse :: [a] -> [a]
|
2024-01-12 17:36:59 +01:00
|
|
|
|
reverse l = revAcc l []
|
2024-01-11 13:38:32 +01:00
|
|
|
|
where
|
2024-01-12 17:36:59 +01:00
|
|
|
|
revAcc [] a = a
|
|
|
|
|
revAcc (x:xs) a = revAcc xs (x:a)
|
2024-01-11 13:38:32 +01:00
|
|
|
|
\end{minted}
|
2024-01-06 15:04:04 +01:00
|
|
|
|
|
2024-01-12 17:36:59 +01:00
|
|
|
|
\mycallout<4->{22, 2}{
|
2024-01-06 15:04:04 +01:00
|
|
|
|
ghci> ones = 1 : ones\\
|
|
|
|
|
ghci> reverse ones\\
|
|
|
|
|
...
|
|
|
|
|
}
|
|
|
|
|
\end{itemize}
|
|
|
|
|
|
2024-01-03 19:51:04 +01:00
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
|
|
\begin{frame}[t, fragile]{Partiality in Agda}{The Maybe Monad}
|
|
|
|
|
In Agda every function has to be total and terminating, so how do we model partial functions?
|
|
|
|
|
|
2024-01-06 15:04:04 +01:00
|
|
|
|
\begin{itemize}[<+->]
|
|
|
|
|
\item Simple errors can be modelled with the maybe monad
|
2024-01-12 17:36:59 +01:00
|
|
|
|
\begin{listing}[H]
|
2024-01-11 13:38:32 +01:00
|
|
|
|
\begin{minted}{agda}
|
2024-01-03 19:51:04 +01:00
|
|
|
|
data Maybe (A : Set) : Set where
|
2024-01-11 13:38:32 +01:00
|
|
|
|
just : A → Maybe A
|
2024-01-03 19:51:04 +01:00
|
|
|
|
nothing : Maybe A
|
2024-01-11 13:38:32 +01:00
|
|
|
|
\end{minted}
|
2024-01-12 17:36:59 +01:00
|
|
|
|
\end{listing}
|
2024-01-03 19:51:04 +01:00
|
|
|
|
|
2024-01-06 15:04:04 +01:00
|
|
|
|
for head we can then do:
|
2024-01-12 17:36:59 +01:00
|
|
|
|
\vskip 0.5cm
|
2024-01-03 19:51:04 +01:00
|
|
|
|
|
2024-01-11 13:38:32 +01:00
|
|
|
|
\begin{minted}{agda}
|
|
|
|
|
head : ∀ A → List A → Maybe A
|
|
|
|
|
head nil = nothing
|
2024-01-03 19:51:04 +01:00
|
|
|
|
head (cons x xs) = just x
|
2024-01-11 13:38:32 +01:00
|
|
|
|
\end{minted}
|
2024-01-03 19:51:04 +01:00
|
|
|
|
|
2024-01-11 13:38:32 +01:00
|
|
|
|
\item What about \mintinline{agda}|reverse|?
|
2024-01-06 15:04:04 +01:00
|
|
|
|
\end{itemize}
|
2024-01-03 19:51:04 +01:00
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
|
|
\begin{frame}[t, fragile]{Partiality in Agda}{Capretta's Delay Monad}
|
2024-01-06 15:04:04 +01:00
|
|
|
|
\begin{itemize}[<+->]
|
|
|
|
|
\item Capretta's Delay Monad is a \textbf{coinductive} data type whose inhabitants can be viewed as suspended computations.
|
2024-01-11 13:38:32 +01:00
|
|
|
|
\begin{minted}{agda}
|
2024-01-03 19:51:04 +01:00
|
|
|
|
data Delay (A : Set) : Set where
|
2024-01-11 13:38:32 +01:00
|
|
|
|
now : A → Delay A
|
|
|
|
|
later : ∞ (Delay A) → Delay A
|
|
|
|
|
\end{minted}
|
2024-01-06 15:04:04 +01:00
|
|
|
|
\item The delay datatype contains a constant for non-termination:
|
2024-01-11 13:38:32 +01:00
|
|
|
|
\begin{minted}{agda}
|
2024-01-03 19:51:04 +01:00
|
|
|
|
never : Delay A
|
2024-01-11 13:38:32 +01:00
|
|
|
|
never = later (♯ never)
|
|
|
|
|
\end{minted}
|
2024-01-06 15:04:04 +01:00
|
|
|
|
\item and we can define a function for \textit{running} a computation (for some amount of steps):
|
2024-01-03 19:51:04 +01:00
|
|
|
|
|
2024-01-11 13:38:32 +01:00
|
|
|
|
\begin{minted}{agda}
|
|
|
|
|
run_for_steps : Delay A → ℕ → Delay A
|
2024-01-03 19:51:04 +01:00
|
|
|
|
run now x for n steps = now x
|
|
|
|
|
run later x for zero steps = later x
|
2024-01-11 13:38:32 +01:00
|
|
|
|
run later x for suc n steps = run ♭ x for n steps
|
|
|
|
|
\end{minted}
|
2024-01-06 15:04:04 +01:00
|
|
|
|
\end{itemize}
|
2024-01-03 19:51:04 +01:00
|
|
|
|
\end{frame}
|
|
|
|
|
|
2024-01-06 15:04:04 +01:00
|
|
|
|
\begin{frame}[c, fragile]{Partiality in Agda}{Reversing (possibly infinite) lists}
|
|
|
|
|
\centering
|
2024-01-11 13:38:32 +01:00
|
|
|
|
\begin{minted}{agda}
|
|
|
|
|
reverse : ∀ {A : Set} → Colist A → Delay (Colist A)
|
2024-01-12 17:36:59 +01:00
|
|
|
|
reverse {A} = revAcc []
|
2024-01-03 19:51:04 +01:00
|
|
|
|
where
|
2024-01-12 17:36:59 +01:00
|
|
|
|
revAcc : Colist A → Colist A → Delay (Colist A)
|
|
|
|
|
revAcc [] a = now a
|
|
|
|
|
revAcc (x ∷ xs) a = later (♯ revAcc (♭ xs) (x ∷ (♯ a)))
|
2024-01-11 13:38:32 +01:00
|
|
|
|
\end{minted}
|
2023-12-14 14:54:23 +01:00
|
|
|
|
\end{frame}
|