Type-level SEO with Idris

Jan Schulte

What is SEO?

How can we improve?

  1. Pay tons of $$$ on adverts
  2. 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

  1. Route element
  2. Route
  3. 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 Integer
data List : (elem : Type) -> Type where
data Vect : (len : Nat) -> (elem : Type) -> Type where
Idris> [1,2,3]
[1, 2, 3] : List Int
Idris> the (Vect _ Int) [1,2,3]
[1, 2, 3] : Vect 3 Int
StringOrNat : Nat -> Type
StringOrNat Z = String
StringOrNat (S n) = Nat
divide : (x:Nat) -> (y:Nat) -> StringOrNat y
divide x Z = "Divisor was 0"
divide x y @ (S n) = div x y
Idris> divide 10 2
5 : Nat
Idris> divide 10 0
"Divisor was 0" : String

Rule 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" footballHandler

Should 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

Made with Slides.com