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 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
Typelevel SEO with Idris
By Jan Schulte
Typelevel SEO with Idris
- 446