Евгений Котельников. Зависимые типы в haskell
DESCRIPTION
Системы зависимых типов позволяют оперировать данными на уровне типов, что может значительно повысить точность спецификации программ. Несмотря на отсутствие поддержки самих зависимых типов в Haskell, некоторые их свойства могут быть реализованы с помощью расширений языка. Будет представлен ряд техник, приближающий Haskell к возможностям языков вроде Agda, Coq и Epigram. Доклад имеет вводный характер и не требует предварительных знаний в обсуждаемых в нём темах.TRANSCRIPT
![Page 1: Евгений Котельников. Зависимые типы в Haskell](https://reader031.vdocuments.pub/reader031/viewer/2022020122/5550f418b4c905417d8b55d8/html5/thumbnails/1.jpg)
Зависимые типы в Haskell
Котельников Евгений
SpbHUG/FProg
12 июля 2012
![Page 2: Евгений Котельников. Зависимые типы в Haskell](https://reader031.vdocuments.pub/reader031/viewer/2022020122/5550f418b4c905417d8b55d8/html5/thumbnails/2.jpg)
Типы и термы
В большинстве языков программирования существует какминимум два мира — мир термов и мир типов.
Мир типовInteger, String → String, ∀ Nat. Nat → String
Мир термов10, "foobar", n, \x -> x + 1, 6 + 5
Между объектами этих двух миров могут возникатьфункциональные зависимости.
![Page 3: Евгений Котельников. Зависимые типы в Haskell](https://reader031.vdocuments.pub/reader031/viewer/2022020122/5550f418b4c905417d8b55d8/html5/thumbnails/3.jpg)
Типы и термы
Зависимость терма от терма
int increment(int x) {return x + 1 ;
}
Зависимость терма от типаПолиморфные функции
static <T> List<T> singletonList(T elem) {ArrayList<T> list = new ArrayList<T>( ) ;list.add(elem) ;return list ;
}
![Page 4: Евгений Котельников. Зависимые типы в Haskell](https://reader031.vdocuments.pub/reader031/viewer/2022020122/5550f418b4c905417d8b55d8/html5/thumbnails/4.jpg)
Типы и термы
Зависимость типа от типаОператоры над типами
Collection <A>
Зависимость типа от термаЗависимые типы
nil : {A : Type} → Vector 0 Acons : {n : Nat} → {A : Type} →
Vector n A → Vector (n + 1) A
![Page 5: Евгений Котельников. Зависимые типы в Haskell](https://reader031.vdocuments.pub/reader031/viewer/2022020122/5550f418b4c905417d8b55d8/html5/thumbnails/5.jpg)
Выражаемое в зависимых типах
I Операции над списками и матрицами сконтролируемыми размерностями
append : {n m : Nat} → {A : Type} →Vector n A → Vector m A → Vector (n + m) A
append nil ys = ysappend (cons x xs) ys = cons x (append xs ys)
I Отсортированные спискиI Сбалансированные деверьяI Функции с переменным числом аргументовI Типо-безопасные printf и scanf
![Page 6: Евгений Котельников. Зависимые типы в Haskell](https://reader031.vdocuments.pub/reader031/viewer/2022020122/5550f418b4c905417d8b55d8/html5/thumbnails/6.jpg)
Код, содержащий доказательства
Системы зависимых типов порождают предикатную логику(см. соответствие Карри-Говарда). Тип — утверждение окоде, терм — доказательство.
Класс типа функтора в Coq
Class Functor (𝜑 : Type → Type) := {fmap : ∀ {𝛼 𝛽} , (𝛼→ 𝛽) → 𝜑 𝛼→ 𝜑 𝛽 ;
(** Functor laws **)fmap_id : ∀ 𝛼 (x : 𝜑 𝛼) , fmap id x = x ;fmap_comp : ∀ 𝛼 𝛽 𝛾 (x : 𝜑 𝛼) (f : 𝛽 → 𝛾) (g : 𝛼→ 𝛽) ,
fmap (f ∘ g) x = (fmap f ∘ fmap g) x} .
Экземпляры класса, помимо самой реализации fmap,обязаны предоставить доказательства теорем о ней.
![Page 7: Евгений Котельников. Зависимые типы в Haskell](https://reader031.vdocuments.pub/reader031/viewer/2022020122/5550f418b4c905417d8b55d8/html5/thumbnails/7.jpg)
Экземпляр класса типа функтора
Instance list_functor : Functor list := {fmap 𝛼 𝛽 := fix fmap f xs := match xs with
| [] ⇒ []| x : : xs ⇒ (f x) : : (fmap f xs)end
} .Proof .(** fmap_id **)intros .induction x as [| x xs] .
reflexivity .rewrite IHxs . reflexivity .
(** fmap_comp **)intros .induction x as [| x xs] .
reflexivity .rewrite IHxs . reflexivity .
Qed .
![Page 8: Евгений Котельников. Зависимые типы в Haskell](https://reader031.vdocuments.pub/reader031/viewer/2022020122/5550f418b4c905417d8b55d8/html5/thumbnails/8.jpg)
Вычисления в типах
Пример: умножение матриц
multiply : {n m q : Nat} →Matrix m n → Matrix n q → Matrix m q
ПроблемаНеобходимо на этапе компиляции проверить, что ширинаодной матрицы равна высоте другой. А в общем случае —проверить на равенство два терма.
Решение (?)Вычислить оба терма до достижения нормальной формы исравнивать их. Но вычисление может никогда незавершиться...
![Page 9: Евгений Котельников. Зависимые типы в Haskell](https://reader031.vdocuments.pub/reader031/viewer/2022020122/5550f418b4c905417d8b55d8/html5/thumbnails/9.jpg)
Вычислительные модели в типах
Допускать только термы специального видаВместо редукций — разрешение системы ограничений.Dependent ML, ATS
Контроль над временем проверки типовЛимит на макс. допустимое количество шагов редукции.Cayenne
Сильная нормализацияОбщая рекурсия запрещена, везде тотальные функции.Coq
Отдельная проверка на тотальностьОбщая рекурсия разрешена, но отдельный механизмпытается распознать нетотальные функции.Agda, Epigram, Idris
![Page 10: Евгений Котельников. Зависимые типы в Haskell](https://reader031.vdocuments.pub/reader031/viewer/2022020122/5550f418b4c905417d8b55d8/html5/thumbnails/10.jpg)
Зависимые типы в Haskell
ИдеяОпределить термы, структура которых повторяет структурусвоих типов.
Натуральные числа в арифметике Пеано
data Nat = Zero | Suc Nat
Натуральные числа как singleton types
data Zero = Zerodata Suc n = Suc n
Структура типа повторяет структуру терма
Suc Zero : : Suc ZeroSuc $ Suc $ Suc Zero : : Suc (Suc (Suc Zero) )
![Page 11: Евгений Котельников. Зависимые типы в Haskell](https://reader031.vdocuments.pub/reader031/viewer/2022020122/5550f418b4c905417d8b55d8/html5/thumbnails/11.jpg)
Определение типа вектора
Обобщённые алгебраические типы данных
{-# LANGUAGE GADTs #-}{-# LANGUAGE GADTSyntax #-}
data Vector n a whereVNil : : Vector Zero aVCons : : a → Vector n a → Vector (Suc n) a
В типе вектора содержится длина
vec4 : : Vector (Suc (Suc (Suc (Suc Zero) ) ) ) Intvec4 = VCons 1 $ VCons 2 $ VCons 3 $ VCons 4 VNil
![Page 12: Евгений Котельников. Зависимые типы в Haskell](https://reader031.vdocuments.pub/reader031/viewer/2022020122/5550f418b4c905417d8b55d8/html5/thumbnails/12.jpg)
Безопасные head и tail
Ограничение на длину задано в типе
vhead : : Vector (Suc n) a → avhead (VCons a _) = a
vtail : : Vector (Suc n) a → Vector n avtail (VCons _ v) = v
Проверка типов отвергает некорректные применения
vhead (VCons 1 $ VCons 2 VNil) -- okvhead VNil -- type error
vtail (VCons 1 $ VCons 2 VNil) -- okvtail VNil -- type error
![Page 13: Евгений Котельников. Зависимые типы в Haskell](https://reader031.vdocuments.pub/reader031/viewer/2022020122/5550f418b4c905417d8b55d8/html5/thumbnails/13.jpg)
K-тый элемент вектора
Мультипараметрические классы типов
{-# LANGUAGE MultiParamTypeClasses #-}
class Kth n k wherekth : : Vector n a → k → a
instance Kth (Suc n’) Zero wherekth (VCons a _) _ = a
instance Kth n’ k’ ⇒ Kth (Suc n’) (Suc k’) wherekth (VCons _ v) (Suc k’) = nth v k’
Pattern matching по типам вместо термов
kth (VCons 1 $ VCons 2 $ VCons 3 VNil) (Suc $ Suc Zero) -- okkth (VCons 1 $ VCons 2 VNil) (Suc $ Suc $ Suc Zero) -- fail
![Page 14: Евгений Котельников. Зависимые типы в Haskell](https://reader031.vdocuments.pub/reader031/viewer/2022020122/5550f418b4c905417d8b55d8/html5/thumbnails/14.jpg)
Конкатенация векторовСемейства типов{-# LANGUAGE TypeFamilies #-}type family Plus n mtype instance Plus Zero m = mtype instance Plus (Suc n’) m = Suc (Plus n’ m)
Можно инфиксно!
{-# LANGUAGE TypeOperators #-}type family n :+ mtype instance Zero :+ m = mtype instance (Suc n’) :+ m = Suc (n’ :+ m)
Конкатенация, сохраняющая длину
append : : Vector n a → Vector m a → Vector (n :+ m) aappend VNil v = vappend (VCons a w) v = VCons a (append w v)
![Page 15: Евгений Котельников. Зависимые типы в Haskell](https://reader031.vdocuments.pub/reader031/viewer/2022020122/5550f418b4c905417d8b55d8/html5/thumbnails/15.jpg)
Литература: зависимые типы
1. B. Pierce. Types and Programming Languages. Chapter30.5
2. B. Pierce et al. Advanced Topics in Types andProgramming Languages. Chapter 2
3. T. Altenkirch, C. McBride, J. McKinna. Why DependentTypes Matter
4. A. Bove, P. Dybjer. Dependent Types at Work5. U. Norell. Dependently Typed Programming in Agda6. H. Xi. Dependent Types in Practical Programming
![Page 16: Евгений Котельников. Зависимые типы в Haskell](https://reader031.vdocuments.pub/reader031/viewer/2022020122/5550f418b4c905417d8b55d8/html5/thumbnails/16.jpg)
Литература: программирование в типах Haskell
1. C. McBride. Faking It: Simulation Dependent Types inHaskell
2. O. Kiselyov, S. Peyton Jones, C. Shan. Fun with typefunctions
3. B. Yorgey. Typed type-level programming in Haskell4. W. Jeltsch. Dependently typed programming and theorem
proving in Haskell
![Page 17: Евгений Котельников. Зависимые типы в Haskell](https://reader031.vdocuments.pub/reader031/viewer/2022020122/5550f418b4c905417d8b55d8/html5/thumbnails/17.jpg)
Вопросы?