Hacker Public Radio

HPR3535: template Haskell


Listen Later

There's certain amount of boilerplate code in my game that keeps repeating time after time. I can't quite remove it, but I can hide it with template haskell.
newtype recap
I'll be using PlanetName as an example throughout the show. newtype is Haskell's way of defining a new type, that wraps around an old type. This lets us to give better meaning to the wrapped type. Instead of talking about Text, we can talk about PlanetName and we won't accidentally mix it up with StarName or ContentsOfAlexandrianLibrary. It comes with no performance cost at all, as the wrapping is removed during the compilation.
Below is how our PlanetName is defined:
newtype PlanetName
= MkPlanetName {_unPlanetName :: Text}
deriving (Show, Read, Eq)
It has:
type constructor PlanetName
data constructor MkPlanetName
single field _unPlanetName
type for that field Text
deriving clause, telling compiler to automatically generate Show, Read and Eq instances
If it were wrapping a Integer, we would add Ord and Num instances too.
These instances give us some basic functions that we can use to turn out value into String and back or compare two values to see if they're equal or not. Ord lets us compare their relative size and Num adds some basic arithmetics like addition and subtraction.
Remember, type constructor is used when talking about the type (function signatures, declaring type of a value, etc.), while data constructor is used to create values of the type ("Earth", "Mars", etc.). isPlanet :: PlanetName -> Bool states that isPlanet function takes one parameter of type PlanetName and returns value of type Bool. planet = MkPlanetName "Earth" creates a new value planet, that has type PlanetName and which value is MkPlanetName "Earth".
Boilerplate
When PlanetName is defined, I need to add some instances by hand: IsString, ToJSON, FromJSON, PersistField and PersistFieldSql.
IsString lets me use string literals in code, without having to call the data constructor. Compiler is smart enough to infer from context if string I typed should be PlanetName or something else.
ToJSON and FromJSON are used to turn value to and from json for transferring back and forth between client and server. In json our value is just simple string, but we still need to program that transformation.
PersistFieldSql tells Persistent (database layer I'm using) what type of database field should be created to hold this data in database.
PersistField contains functions for serializing our value to database and loading it from there.
Below is full code that I want to abstract out as much as I can:
newtype PlanetName
= MkPlanetName {_unPlanetName :: Text}
deriving (Show, Read, Eq)
instance IsString PlanetName where
fromString = (MkPlanetName . fromString)
instance ToJSON PlanetName where
toJSON = (toJSON . _unPlanetName)
instance FromJSON PlanetName where
parseJSON = (withText "PlanetName") (return . MkPlanetName)
instance PersistField PlanetName where
toPersistValue (MkPlanetName s) = PersistText s
fromPersistValue (PersistText s) = (Right $ MkPlanetName s)
fromPersistValue _ = Left "Failed to deserialize"
instance PersistFieldSql PlanetName where
sqlT
...more
View all episodesView all episodes
Download on the App Store

Hacker Public RadioBy Hacker Public Radio

  • 4.2
  • 4.2
  • 4.2
  • 4.2
  • 4.2

4.2

34 ratings


More shows like Hacker Public Radio

View all
The Changelog: Software Development, Open Source by Changelog Media

The Changelog: Software Development, Open Source

290 Listeners

Defensive Security Podcast - Malware, Hacking, Cyber Security & Infosec by Jerry Bell and Andrew Kalat

Defensive Security Podcast - Malware, Hacking, Cyber Security & Infosec

372 Listeners

LINUX Unplugged by Jupiter Broadcasting

LINUX Unplugged

268 Listeners

SANS Internet Stormcenter Daily Cyber Security Podcast (Stormcast) by Johannes B. Ullrich

SANS Internet Stormcenter Daily Cyber Security Podcast (Stormcast)

651 Listeners

Curious Cases by BBC Radio 4

Curious Cases

821 Listeners

The Strong Towns Podcast by Strong Towns

The Strong Towns Podcast

423 Listeners

Late Night Linux by The Late Night Linux Family

Late Night Linux

164 Listeners

Darknet Diaries by Jack Rhysider

Darknet Diaries

8,059 Listeners

Cybersecurity Today by Jim Love

Cybersecurity Today

179 Listeners

CISO Series Podcast by David Spark, Mike Johnson, and Andy Ellis

CISO Series Podcast

189 Listeners

TechCrunch Daily Crunch by TechCrunch

TechCrunch Daily Crunch

42 Listeners

Strict Scrutiny by Crooked Media

Strict Scrutiny

5,800 Listeners

2.5 Admins by The Late Night Linux Family

2.5 Admins

98 Listeners

Cyber Security Headlines by CISO Series

Cyber Security Headlines

139 Listeners

What the Hack? by DeleteMe

What the Hack?

228 Listeners