Lens generator in Persistent

January 1, 2014

GravatarBy Michael Snoyman

I've just released version 1.3.1 of persistent-template, which adds a new options: mpsGenerateLenses. When enabled, this option will cause lenses to be generated instead of normal field accessors. An example is worth a thousand words:

{-# LANGUAGE EmptyDataDecls    #-}
{-# LANGUAGE FlexibleContexts  #-}
{-# LANGUAGE GADTs             #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes       #-}
{-# LANGUAGE TemplateHaskell   #-}
{-# LANGUAGE TypeFamilies      #-}
import           Control.Monad.IO.Class  (liftIO)
import           Database.Persist
import           Database.Persist.Sqlite
import           Database.Persist.TH
import           Control.Lens

share
  [ mkPersist sqlSettings { mpsGenerateLenses = True }
  , mkMigrate "migrateAll"
  ] [persistLowerCase|
Person
    name String
    age Int Maybe
    deriving Show
|]

main :: IO ()
main = runSqlite ":memory:" $ do
    runMigration migrateAll

    johnId <- insert $ Person "John Doe" $ Just 35

    Just john <- get johnId

    liftIO $ putStrLn $ john ^. personName

    janeId <- insert $ john & personName .~ "Jane Joe"
    Just jane <- get janeId
    liftIO $ print jane

Not a major feature, but convenient. It can also be combined with the relatively new mpsPrefixFields option if your field names are unique, e.g.:

share
  [ mkPersist sqlSettings { mpsGenerateLenses = True, mpsPrefixFields = False }
  , mkMigrate "migrateAll"
  ] [persistLowerCase|
Person
    name String
    age Int Maybe
    deriving Show
|]

main :: IO ()
main = runSqlite ":memory:" $ do
    runMigration migrateAll

    johnId <- insert $ Person "John Doe" $ Just 35

    Just john <- get johnId

    liftIO $ putStrLn $ john ^. name

    janeId <- insert $ john & name .~ "Jane Joe"
    Just jane <- get janeId
    liftIO $ print jane

Note that this isn't the first use of lenses in Persistent. While this implementation is fully compatible with the lens package, it introduces no dependency on that package, due to the beautiful way in which lenses work.

Comments

comments powered by Disqus

Archives