SlideShare a Scribd company logo
Introduction to Idris
Conor Farrell
Lambda Lounge Manchester June 2018
Who am I?
● Developer for ~10 years
● Java/Clojure/Python/Node/XQuery
● Contractor with Equal Experts
● Soft spot for esolangs
Who am I?
Unfortunately, I:
● Don’t know Haskell very well!
● Don’t have a Computer Science/Maths background!
Luckily, you don’t need either.
Making Software. Better.
Simple solutions to big business problems.
Equal Experts is a network of talented, experienced, software
consultants, specialising in agile delivery.
Who is Idris?
Who is Idris?
What is Idris?
● Pure functional language with dependent types
● Compiled, eagerly evaluated
● Totality checking
● Theorem proving
● REPL + compiler interactive editing support
● Almost-but-not-quite Haskell syntax
Where can I get Idris?
https://www.idris-lang.org/
Mac: brew install idris
Linux: Install Cabal, then cabal install idris
Windows: Prebuilt binaries (or more esoteric methods)
Obligatory ‘Hello World’
module Main
main : IO ()
main = putStrLn "Rigorously proven hello world"
Obligatory ‘Hello World’
A pure language, so it defers actually doing anything to
‘something else’...
Compiler Editor Support
Idris’s compiler helps out when you’re writing code...
● Clause creation
● Case splitting
● Type checking
● Proof search
● & more...
Provided you’re using one of Atom/Emacs/Sublime/Vim!
Compiler Editor Support
myPlus : Nat -> Nat -> Nat
As is traditional, let’s reimplement a library function!
Nat is a type that represents a natural (i.e. non-negative)
number.
The function myPlus takes two Nats and returns a Nat.
Compiler Editor Support
myPlus : Nat -> Nat -> Nat
Generate clause (d), leads to...
Compiler Editor Support
myPlus : Nat -> Nat -> Nat
myPlus k j : ?myPlusRhs
The bit with a ? is called a ‘hole’ - it signifies something to be
filled in later.
This lets us write functions incrementally.
Compiler Editor Support
myPlus : Nat -> Nat -> Nat
myPlus k j : ?myPlusRhs
Case split (c) on k...
Compiler Editor Support
myPlus : Nat -> Nat -> Nat
myPlus Z j : ?myPlusRhs1
myPlus (S k) j : ?myPlusRhs2
Obvious proof search (o) on ?myPlusRhs1 gives...
Compiler Editor Support
myPlus : Nat -> Nat -> Nat
myPlus Z j : j
myPlus (S k) j : ?myPlusRhs2
Leaving only the last bit to fill in...
Compiler Editor Support
myPlus : Nat -> Nat -> Nat
myPlus Z j : j
myPlus (S k) j : S (myPlus k j)
Done! We can also verify the function is total.
Only total functions will be evaluated during type checking.
Total functions
To be total, a function f must:
● Cover all possible inputs
● Be well-founded
● Not use any data types which are not strictly positive
● Not call any non-total functions
Dependent types
Types in Idris are first-class - a function can be passed and can
return a type.
isSingleton : Bool -> Type
isSingleton True = Nat
isSingleton False = List Nat
mkSingle : (x : Bool) -> isSingleton x
mkSingle True = 0
mkSingle False = []
Dependent types
Vect represents a list with a Nat length.
Vect lets us express stronger guarantees about the inputs and
outputs to a function.
myReverse : List t -> List t
myReverse xs = []
Clearly this won’t do what it should, but it does compile!
Dependent types
import Data.Vect
myReverse : Vect n t -> Vect n t
myReverse xs = []
The above code won’t even compile!
Records
Records collect several types (the record’s fields) together.
record Person where
constructor MkPerson
firstName, lastName : String
age : Int
batman : Person
batman = MkPerson "Bruce" "Wayne" 52
Records
The field names can be used to access the values.
Records
The field names can also be used to create a modified copy of
the record.
means ‘apply this function to update’
Records
Nested fields, e.g. c(b (a x)) can be accessed/updated using the
syntax:
Interfaces
An interface defines a function usable across multiple types,
similar to Haskell type classes.
interface Show a where
show : a -> String
This will generate the method:
show : Show a => a -> String
Theorem proving
Like Agda and Coq, Idris can be used to prove theorems. Let’s
try to prove something easy!
0 + x = x
All we need is to create a program with a precise enough type,
thanks to the Curry-Howard correspondence.
Disclaimer: I am not a mathematician!
Theorem proving
Expressing this in Idris:
plusReduces : (n: Nat) -> plus Z n = n
Asking the compiler to create a clause (d) gives us...
Theorem proving
plusReduces : (n: Nat) -> plus Z n = n
plusReduces n = ?plusReduces_rhs
Performing a proof search (o) gives us...
Theorem proving
plusReduces : (n: Nat) -> plus Z n = n
plusReduces n = Refl
Refl (reflexive) indicates that a value is equal to itself.
We can only return Refl if the values actually are equal!
Theorem proving
nineteeneightyfour : 2 + 2 = 5
nineteeneightyfour = Refl
The compiler will complain if we try this:
Theorem proving
To express that a proposition is impossible:
nineteeneightyfour : 2 + 2 = 5 -> Void
nineteeneightyfour prf = ?rhs
The Void type indicates a type which cannot be constructed.
Case split (c) on prf and we get...
Theorem proving
nineteeneightyfour : 2 + 2 = 5 -> Void
nineteeneightyfour Refl impossible
impossible tells Idris that the value cannot be constructed.
Theorem proving
We should check that a function that returns Void is a total
function!
Otherwise, you could write a function that claims to return
Void by looping forever:
loop : Void
loop = loop
Theorem proving
What if we want to prove the same theorem about addition
reduction, with the arguments reversed?
x + 0 = x
Shouldn’t this be the same proof?
Unfortunately, the proof depends on Idris’ implementation of
plus.
Theorem proving
plusReduces : (n: Nat) -> plus n Z = n
plusReduces Z = Refl
plusReduces (S k) = ?plusReduces_rhs
The type of ?plusReduces_rhs is S (plus k 0) = S k.
We know we need to use plusReduces k so we can recurse
down to the base case. Let’s refine by using a hole.
Theorem proving
plusReduces : (n: Nat) -> plus n Z = n
plusReduces Z = Refl
plusReduces (S k) = ?prf (plusReduces k)
The type of ?prf is (plus k 0 = k) -> S (plus k 0) = S k.
In other words, we need to tell Idris that applying S doesn’t
change the truth of the proof.
Theorem proving
plusReduces : (n: Nat) -> plus n Z = n
plusReduces Z = Refl
plusReduces (S k) = cong (plusReduces k)
cong (congruence) is a library function which states that
equality respects function application:
cong : {f : t -> u} -> a = b -> f a = f b
Dependent Types Redux
It should be easy to remove an element from a Vect...right?
removeElem : DecEq a => (value : a) -> (xs : Vect (S n) a) -> Vect n a
DecEq is an interface which allows you to state two values are
equal.
Dependent Types Redux
Taking a naive approach, we eventually get:
removeElem : DecEq a => (value : a) -> (xs : Vect (S n) a) -> Vect n a
removeElem value (x :: xs) = case decEq value x of
Yes prf => xs
No contra => x :: removeElem value xs
But this won’t compile! We’ve said that the Vect will be
non-empty (S n) but we may generate an empty Vect if we
don’t find the element to remove.
Dependent Types Redux
What we need is a proof that the value to remove is actually in
the Vect.
The built-in Elem type gives us this. Its signature is:
data Elem : a -> Vect k a -> Type where
Here : Elem x (x :: xs)
There : (later : Elem x xs) -> Elem x (y :: xs)
Dependent Types Redux
Let’s try again, with an Elem as proof.
removeElem : (value : a) ->
(xs : Vect (S n) a) ->
(prf : Elem value xs) ->
Vect n a
removeElem value xs prf = ?removeElem_rhs
Case split on prf...
Dependent Types Redux
removeElem : (value : a) ->
(xs : Vect (S n) a) ->
(prf : Elem value xs) ->
Vect n a
removeElem value (value :: ys) Here = ?removeElem_rhs1
removeElem value (y :: ys) (There later) = ?removeElem_rhs2
The first case is trivial, the second less so.
Dependent Types Redux
removeElem : (value : a) ->
(xs : Vect (S n) a) ->
(prf : Elem value xs) ->
Vect n a
removeElem value (value :: ys) Here = ys
removeElem value (y :: ys) (There later) = ?removeElem_rhs2
prf proves that the value exists in ys and so must have a
nonzero length.
Dependent Types Redux
Bringing the implicit variable n into scope and case splitting on
it:
removeElem : (value : a) ->
(xs : Vect (S n) a) ->
(prf : Elem value xs) ->
Vect n a
removeElem value (value :: ys) Here = ys
removeElem {n = Z} value (y :: ys) (There later) = ?removeElem_rhs1
removeElem {n = (S k)} value (y :: ys) (There later) = ?removeElem_rhs2
Dependent Types Redux
We know ys has a nonzero length in the second hole:
removeElem : (value : a) ->
(xs : Vect (S n) a) ->
(prf : Elem value xs) ->
Vect n a
removeElem value (value :: ys) Here = ys
removeElem {n = Z} value (y :: ys) (There later) = ?removeElem_rhs1
removeElem {n = (S k)} value (y :: ys) (There later)
= y :: removeElem value ys later
Dependent Types Redux
The only remaining case has a proof that the value is present in
an empty Vect, which is clearly contradictory.
We can tell Idris this is so using absurd.
This asserts that its input is of the Uninhabited interface, i.e.
it’s a type with no values.
Dependent Types Redux
removeElem : (value : a) ->
(xs : Vect (S n) a) ->
(prf : Elem value xs) ->
Vect n a
removeElem value (value :: ys) Here = ys
removeElem {n = Z} value (y :: ys) (There later) = absurd later
removeElem {n = (S k)} value (y :: ys) (There later)
= y :: removeElem value ys later
Luckily, you can define arguments as auto to let Idris try to
find them by itself (so you don’t have to prove everything!)
Making Software. Better.
Simple solutions to big business problems.
Thank you!

More Related Content

PDF
Scala taxonomy
PDF
Introduction to Scala for JCConf Taiwan
PDF
First-Class Patterns
PDF
Scala Intro
PDF
Scala jargon cheatsheet
PDF
42.type: Literal-based Singleton types
PDF
Monadologie
PDF
Few simple-type-tricks in scala
Scala taxonomy
Introduction to Scala for JCConf Taiwan
First-Class Patterns
Scala Intro
Scala jargon cheatsheet
42.type: Literal-based Singleton types
Monadologie
Few simple-type-tricks in scala

What's hot (20)

PDF
The Scala Programming Language
PPTX
Scala Back to Basics: Type Classes
PDF
A taste of Functional Programming
PDF
Coding in Style
KEY
Deriving Scalaz
PDF
Introduction to functional programming using Ocaml
PDF
Programming in Scala: Notes
PDF
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
PDF
Futures e abstração - QCon São Paulo 2015
PDF
Programming Android Application in Scala.
PDF
SE 20016 - programming languages landscape.
PDF
OSCON Presentation: Developing High Performance Websites and Modern Apps with...
PDF
[Codemotion 2015] patrones de diseño con java8
PDF
High Wizardry in the Land of Scala
PDF
Scala cheatsheet
PDF
Scala categorytheory
ODP
Scala traits training by Sanjeev Kumar @Kick Start Scala traits & Play, organ...
PDF
Reactive Web Applications with Scala & Liftweb - CodeWeek 2015
PDF
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
PDF
Halogen: Past, Present, and Future
The Scala Programming Language
Scala Back to Basics: Type Classes
A taste of Functional Programming
Coding in Style
Deriving Scalaz
Introduction to functional programming using Ocaml
Programming in Scala: Notes
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Futures e abstração - QCon São Paulo 2015
Programming Android Application in Scala.
SE 20016 - programming languages landscape.
OSCON Presentation: Developing High Performance Websites and Modern Apps with...
[Codemotion 2015] patrones de diseño con java8
High Wizardry in the Land of Scala
Scala cheatsheet
Scala categorytheory
Scala traits training by Sanjeev Kumar @Kick Start Scala traits & Play, organ...
Reactive Web Applications with Scala & Liftweb - CodeWeek 2015
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
Halogen: Past, Present, and Future
Ad

Similar to Introduction to idris (20)

PDF
High-Performance Haskell
PDF
Lecture 3
PDF
Scala by Luc Duponcheel
PPTX
Principles of functional progrmming in scala
PPTX
Столпы функционального программирования для адептов ООП, Николай Мозговой
PDF
Functional programming ii
ODP
Functional Programming With Scala
PPTX
Introduction to Dependently Types: Idris
PDF
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
PDF
Lecture 5: Functional Programming
PDF
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
PDF
Reasoning about laziness
ODP
Introducing scala
ODP
Functional programming with Scala
PDF
TI1220 Lecture 6: First-class Functions
PPT
Functional object
PDF
Monoids - Part 1 - with examples using Scalaz and Cats
PDF
Scala Bootcamp 1
PPTX
Legacy lambda code
PDF
Pydiomatic
High-Performance Haskell
Lecture 3
Scala by Luc Duponcheel
Principles of functional progrmming in scala
Столпы функционального программирования для адептов ООП, Николай Мозговой
Functional programming ii
Functional Programming With Scala
Introduction to Dependently Types: Idris
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
Lecture 5: Functional Programming
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
Reasoning about laziness
Introducing scala
Functional programming with Scala
TI1220 Lecture 6: First-class Functions
Functional object
Monoids - Part 1 - with examples using Scalaz and Cats
Scala Bootcamp 1
Legacy lambda code
Pydiomatic
Ad

Recently uploaded (20)

PDF
cuic standard and advanced reporting.pdf
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Encapsulation theory and applications.pdf
PPTX
Spectroscopy.pptx food analysis technology
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
Review of recent advances in non-invasive hemoglobin estimation
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PPTX
Cloud computing and distributed systems.
PPTX
Programs and apps: productivity, graphics, security and other tools
cuic standard and advanced reporting.pdf
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Mobile App Security Testing_ A Comprehensive Guide.pdf
Encapsulation theory and applications.pdf
Spectroscopy.pptx food analysis technology
Per capita expenditure prediction using model stacking based on satellite ima...
The AUB Centre for AI in Media Proposal.docx
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
MIND Revenue Release Quarter 2 2025 Press Release
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Review of recent advances in non-invasive hemoglobin estimation
Understanding_Digital_Forensics_Presentation.pptx
Network Security Unit 5.pdf for BCA BBA.
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Dropbox Q2 2025 Financial Results & Investor Presentation
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Cloud computing and distributed systems.
Programs and apps: productivity, graphics, security and other tools

Introduction to idris

  • 1. Introduction to Idris Conor Farrell Lambda Lounge Manchester June 2018
  • 2. Who am I? ● Developer for ~10 years ● Java/Clojure/Python/Node/XQuery ● Contractor with Equal Experts ● Soft spot for esolangs
  • 3. Who am I? Unfortunately, I: ● Don’t know Haskell very well! ● Don’t have a Computer Science/Maths background! Luckily, you don’t need either.
  • 4. Making Software. Better. Simple solutions to big business problems. Equal Experts is a network of talented, experienced, software consultants, specialising in agile delivery.
  • 7. What is Idris? ● Pure functional language with dependent types ● Compiled, eagerly evaluated ● Totality checking ● Theorem proving ● REPL + compiler interactive editing support ● Almost-but-not-quite Haskell syntax
  • 8. Where can I get Idris? https://www.idris-lang.org/ Mac: brew install idris Linux: Install Cabal, then cabal install idris Windows: Prebuilt binaries (or more esoteric methods)
  • 9. Obligatory ‘Hello World’ module Main main : IO () main = putStrLn "Rigorously proven hello world"
  • 10. Obligatory ‘Hello World’ A pure language, so it defers actually doing anything to ‘something else’...
  • 11. Compiler Editor Support Idris’s compiler helps out when you’re writing code... ● Clause creation ● Case splitting ● Type checking ● Proof search ● & more... Provided you’re using one of Atom/Emacs/Sublime/Vim!
  • 12. Compiler Editor Support myPlus : Nat -> Nat -> Nat As is traditional, let’s reimplement a library function! Nat is a type that represents a natural (i.e. non-negative) number. The function myPlus takes two Nats and returns a Nat.
  • 13. Compiler Editor Support myPlus : Nat -> Nat -> Nat Generate clause (d), leads to...
  • 14. Compiler Editor Support myPlus : Nat -> Nat -> Nat myPlus k j : ?myPlusRhs The bit with a ? is called a ‘hole’ - it signifies something to be filled in later. This lets us write functions incrementally.
  • 15. Compiler Editor Support myPlus : Nat -> Nat -> Nat myPlus k j : ?myPlusRhs Case split (c) on k...
  • 16. Compiler Editor Support myPlus : Nat -> Nat -> Nat myPlus Z j : ?myPlusRhs1 myPlus (S k) j : ?myPlusRhs2 Obvious proof search (o) on ?myPlusRhs1 gives...
  • 17. Compiler Editor Support myPlus : Nat -> Nat -> Nat myPlus Z j : j myPlus (S k) j : ?myPlusRhs2 Leaving only the last bit to fill in...
  • 18. Compiler Editor Support myPlus : Nat -> Nat -> Nat myPlus Z j : j myPlus (S k) j : S (myPlus k j) Done! We can also verify the function is total. Only total functions will be evaluated during type checking.
  • 19. Total functions To be total, a function f must: ● Cover all possible inputs ● Be well-founded ● Not use any data types which are not strictly positive ● Not call any non-total functions
  • 20. Dependent types Types in Idris are first-class - a function can be passed and can return a type. isSingleton : Bool -> Type isSingleton True = Nat isSingleton False = List Nat mkSingle : (x : Bool) -> isSingleton x mkSingle True = 0 mkSingle False = []
  • 21. Dependent types Vect represents a list with a Nat length. Vect lets us express stronger guarantees about the inputs and outputs to a function. myReverse : List t -> List t myReverse xs = [] Clearly this won’t do what it should, but it does compile!
  • 22. Dependent types import Data.Vect myReverse : Vect n t -> Vect n t myReverse xs = [] The above code won’t even compile!
  • 23. Records Records collect several types (the record’s fields) together. record Person where constructor MkPerson firstName, lastName : String age : Int batman : Person batman = MkPerson "Bruce" "Wayne" 52
  • 24. Records The field names can be used to access the values.
  • 25. Records The field names can also be used to create a modified copy of the record. means ‘apply this function to update’
  • 26. Records Nested fields, e.g. c(b (a x)) can be accessed/updated using the syntax:
  • 27. Interfaces An interface defines a function usable across multiple types, similar to Haskell type classes. interface Show a where show : a -> String This will generate the method: show : Show a => a -> String
  • 28. Theorem proving Like Agda and Coq, Idris can be used to prove theorems. Let’s try to prove something easy! 0 + x = x All we need is to create a program with a precise enough type, thanks to the Curry-Howard correspondence. Disclaimer: I am not a mathematician!
  • 29. Theorem proving Expressing this in Idris: plusReduces : (n: Nat) -> plus Z n = n Asking the compiler to create a clause (d) gives us...
  • 30. Theorem proving plusReduces : (n: Nat) -> plus Z n = n plusReduces n = ?plusReduces_rhs Performing a proof search (o) gives us...
  • 31. Theorem proving plusReduces : (n: Nat) -> plus Z n = n plusReduces n = Refl Refl (reflexive) indicates that a value is equal to itself. We can only return Refl if the values actually are equal!
  • 32. Theorem proving nineteeneightyfour : 2 + 2 = 5 nineteeneightyfour = Refl The compiler will complain if we try this:
  • 33. Theorem proving To express that a proposition is impossible: nineteeneightyfour : 2 + 2 = 5 -> Void nineteeneightyfour prf = ?rhs The Void type indicates a type which cannot be constructed. Case split (c) on prf and we get...
  • 34. Theorem proving nineteeneightyfour : 2 + 2 = 5 -> Void nineteeneightyfour Refl impossible impossible tells Idris that the value cannot be constructed.
  • 35. Theorem proving We should check that a function that returns Void is a total function! Otherwise, you could write a function that claims to return Void by looping forever: loop : Void loop = loop
  • 36. Theorem proving What if we want to prove the same theorem about addition reduction, with the arguments reversed? x + 0 = x Shouldn’t this be the same proof? Unfortunately, the proof depends on Idris’ implementation of plus.
  • 37. Theorem proving plusReduces : (n: Nat) -> plus n Z = n plusReduces Z = Refl plusReduces (S k) = ?plusReduces_rhs The type of ?plusReduces_rhs is S (plus k 0) = S k. We know we need to use plusReduces k so we can recurse down to the base case. Let’s refine by using a hole.
  • 38. Theorem proving plusReduces : (n: Nat) -> plus n Z = n plusReduces Z = Refl plusReduces (S k) = ?prf (plusReduces k) The type of ?prf is (plus k 0 = k) -> S (plus k 0) = S k. In other words, we need to tell Idris that applying S doesn’t change the truth of the proof.
  • 39. Theorem proving plusReduces : (n: Nat) -> plus n Z = n plusReduces Z = Refl plusReduces (S k) = cong (plusReduces k) cong (congruence) is a library function which states that equality respects function application: cong : {f : t -> u} -> a = b -> f a = f b
  • 40. Dependent Types Redux It should be easy to remove an element from a Vect...right? removeElem : DecEq a => (value : a) -> (xs : Vect (S n) a) -> Vect n a DecEq is an interface which allows you to state two values are equal.
  • 41. Dependent Types Redux Taking a naive approach, we eventually get: removeElem : DecEq a => (value : a) -> (xs : Vect (S n) a) -> Vect n a removeElem value (x :: xs) = case decEq value x of Yes prf => xs No contra => x :: removeElem value xs But this won’t compile! We’ve said that the Vect will be non-empty (S n) but we may generate an empty Vect if we don’t find the element to remove.
  • 42. Dependent Types Redux What we need is a proof that the value to remove is actually in the Vect. The built-in Elem type gives us this. Its signature is: data Elem : a -> Vect k a -> Type where Here : Elem x (x :: xs) There : (later : Elem x xs) -> Elem x (y :: xs)
  • 43. Dependent Types Redux Let’s try again, with an Elem as proof. removeElem : (value : a) -> (xs : Vect (S n) a) -> (prf : Elem value xs) -> Vect n a removeElem value xs prf = ?removeElem_rhs Case split on prf...
  • 44. Dependent Types Redux removeElem : (value : a) -> (xs : Vect (S n) a) -> (prf : Elem value xs) -> Vect n a removeElem value (value :: ys) Here = ?removeElem_rhs1 removeElem value (y :: ys) (There later) = ?removeElem_rhs2 The first case is trivial, the second less so.
  • 45. Dependent Types Redux removeElem : (value : a) -> (xs : Vect (S n) a) -> (prf : Elem value xs) -> Vect n a removeElem value (value :: ys) Here = ys removeElem value (y :: ys) (There later) = ?removeElem_rhs2 prf proves that the value exists in ys and so must have a nonzero length.
  • 46. Dependent Types Redux Bringing the implicit variable n into scope and case splitting on it: removeElem : (value : a) -> (xs : Vect (S n) a) -> (prf : Elem value xs) -> Vect n a removeElem value (value :: ys) Here = ys removeElem {n = Z} value (y :: ys) (There later) = ?removeElem_rhs1 removeElem {n = (S k)} value (y :: ys) (There later) = ?removeElem_rhs2
  • 47. Dependent Types Redux We know ys has a nonzero length in the second hole: removeElem : (value : a) -> (xs : Vect (S n) a) -> (prf : Elem value xs) -> Vect n a removeElem value (value :: ys) Here = ys removeElem {n = Z} value (y :: ys) (There later) = ?removeElem_rhs1 removeElem {n = (S k)} value (y :: ys) (There later) = y :: removeElem value ys later
  • 48. Dependent Types Redux The only remaining case has a proof that the value is present in an empty Vect, which is clearly contradictory. We can tell Idris this is so using absurd. This asserts that its input is of the Uninhabited interface, i.e. it’s a type with no values.
  • 49. Dependent Types Redux removeElem : (value : a) -> (xs : Vect (S n) a) -> (prf : Elem value xs) -> Vect n a removeElem value (value :: ys) Here = ys removeElem {n = Z} value (y :: ys) (There later) = absurd later removeElem {n = (S k)} value (y :: ys) (There later) = y :: removeElem value ys later Luckily, you can define arguments as auto to let Idris try to find them by itself (so you don’t have to prove everything!)
  • 50. Making Software. Better. Simple solutions to big business problems. Thank you!