Type-level SEO with Idris
Jan Schulte

What is SEO?

How can we improve?
- Pay tons of $$$ on adverts
- Optimise web site for search engines


Rule 1 - Simple-to-understand URLs
- avoid using odd capitalization of URLs
- /This/IS/not/s3o-{frI3ndLy}
Rule 2 - Simple directory structure
- Avoid having deep nesting of subdirectories like ".../dir1/dir2/dir3/dir4/dir5/dir6/page.html"
Rule 3 - Complete directory structure
- Allow for the possibility of a part of the URL being removed
Motivation
- Avoiding SEO problems is hard
- Enforce our rules as early as possible!
⇒ Proof of concept using dependent types in Idris
Site aka URL structure
Routing DSL: Spring
@GetMapping("/sports/basketball")
public ModelMap basketballHandler() {
...
}
Routing DSL: Play
GET /sports/basketball SportsController.basketballHandler
Goal:
Create SEO-conform Routing DSL
Idris routing DSL
Routes (
GET Root homepageHandler &
GET (Root / Literal "sports") sportsHandler &
GET (Root / Literal "sports" / Literal "basketball") basketballHandler
)Compiles
Does not compile
Follows SEO rules?
Breaks SEO rules?
Procedure
- Route element
- Route
- Many routes
Routes (
GET Root homepageHandler &
GET (Root / Literal "sports") sportsHandler &
GET (Root / Literal "sports" / Literal "basketball") basketballHandler
)Idris

data Option : (t:Type) -> Type where
Some : (value:t) -> Option t
None : Option t
add : Int -> Int -> Int
add x y = x + y*intro> Some 5
Some 5 : Option Integerdata List : (elem : Type) -> Type wheredata Vect : (len : Nat) -> (elem : Type) -> Type whereIdris> [1,2,3]
[1, 2, 3] : List IntIdris> the (Vect _ Int) [1,2,3]
[1, 2, 3] : Vect 3 IntStringOrNat : Nat -> Type
StringOrNat Z = String
StringOrNat (S n) = Natdivide : (x:Nat) -> (y:Nat) -> StringOrNat y
divide x Z = "Divisor was 0"
divide x y @ (S n) = div x yIdris> divide 10 2
5 : NatIdris> divide 10 0
"Divisor was 0" : StringRule 1 - Simple-to-understand URLs
- avoid using odd capitalization of URLs
- /This/IS/not/s3o-{frI3ndLy}
Rule 1
Root / Literal "seo-friendly"Root / Literal "{no_~.-$Eo-fRiEndLy}^"Should compile
Should not
compile

Rule 2 - Simple directory structure
- Avoid having deep nesting of subdirectories like ".../dir1/dir2/dir3/dir4/dir5/dir6/page.html"
Rule 2
Root / Literal "category" / Literal "sports" / Literal "football"Root / Literal "category" / Literal "sports" / Literal "ball" / Literal "round" / Literal "foot" Should compile
Should not compile

Rule 3 - Complete directory structure
- Allow for the possibility of a part of the URL being removed
Rule 3
GET Root homepageHandler
GET Root / Literal "sports" sportsHandler
GET Root / Literal "sports" / Literal "football" footballHandlerShould compile
Should not compile
GET Root homepageHandler
GET Root / Literal "sports" / Literal "football" footballHandler
Summary
- Routing DSL
- Compile-time SEO checks
- No macro's - plain Idris
- Automatic proof finding
- Many more SEO rules
compile-time correspondance
curry data dependent function hole howard idris
implicit isomorphism lambda logic monad php proof rankingroutes search seo static types
Thank you!
{slides,github}.com/janschultecom/typelevel-seo
@janschultecom
Hic sunt dracones
About me
- Independent Software Consultant
- Scala for work
- Idris for fun
Rule 4 - Use relevant words in URLs
- URLs with words that are relevant to your site's content and structure are friendlier for visitors navigating your site.
Rule 4
Root / Literal "has-football-keyword"Root / Literal "eyjafjallajokull"Should compile
Should not
compile
Root / Literal "has-no-keyword"Should not
compile
Root / Literal "basketball"Should compile

Typelevel SEO with Idris
By Jan Schulte
Typelevel SEO with Idris
- 569