\begin{frame}[t, fragile]{Partiality in Haskell}{} Haskell allows users to define arbitrary partial functions, some can be spotted easily by their definition: \begin{lstlisting}[language=haskell] head :: [a] -> a head [] = error "empty list" head (x:xs) = x \end{lstlisting} % TODO right of this add error bubble that shows what happens for `head []` others might be more subtle: \begin{lstlisting}[language=haskell] reverse l = rev l [] where rev [] a = a rev (x:xs) a = rev xs (x:a) \end{lstlisting} % TODO right of this add error bubble that shows `reverse ones` \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? \begin{lstlisting} data Maybe (A : Set) : Set where just : A $\rightarrow$ Maybe A nothing : Maybe A \end{lstlisting} for head we can then do: \begin{lstlisting} head : $\forall$ A $\rightarrow$ List A $\rightarrow$ Maybe A head nil = nothing head (cons x xs) = just x \end{lstlisting} But what about \lstinline|reverse|? \end{frame} \begin{frame}[t, fragile]{Partiality in Agda}{Capretta's Delay Monad} Capretta's Delay Monad is a coinductive data type whose inhabitants can be viewed as suspended computations. \begin{lstlisting} data Delay (A : Set) : Set where now : A $\rightarrow$ Delay A later : $\infty$ (Delay A) $\rightarrow$ Delay A \end{lstlisting} \lstinline|now| lifts a computation, while \lstinline|later| delays it by one time unit. The delay datatype contains a constant for non-termination: \begin{lstlisting} never : Delay A never = later ($\sharp$ never) \end{lstlisting} and we can define a function for \textit{running} a computation (for some amount of steps): \begin{lstlisting} run_for_steps : Delay A $\rightarrow$ $\mathbb{N}$ $\rightarrow$ Delay A run now x for n steps = now x run later x for zero steps = later x run later x for suc n steps = run $\flat$ x for n steps \end{lstlisting} \end{frame} \begin{frame}[t, fragile]{Partiality in Agda}{Reversing (possibly infinite) lists} \begin{lstlisting} foldl : $\forall$ {A B : Set} $\rightarrow$ (A $\rightarrow$ B $\rightarrow$ A) $\rightarrow$ A $\rightarrow$ Colist B $\rightarrow$ Delay A foldl c n [] = now n foldl c n (x $\squaredots$ xs) = later ($\sharp$ foldl c (c n x) ($\flat$ xs)) reverse : $\forall$ {A : Set} $\rightarrow$ Colist A $\rightarrow$ Delay (Colist A) reverse {A} = reverseAcc [] where reverseAcc : Colist A $\rightarrow$ Colist A $\rightarrow$ Delay (Colist A) reverseAcc = foldl ($\lambda$ xs x $\rightarrow$ x $\squaredots$ ($\sharp$ xs)) -- 'flip _$\squaredots$_' with extra steps \end{lstlisting} \end{frame}