:
{-
import Language.Haskell.TH
, :
data Person = Person Int String deriving Show
class SQL a where
fromSql :: String -> a
instance SQL Int where fromSql = read
instance SQL String where fromSql = id
, , . , makeModel ( ):
LamE [ListP [VarP id,VarP name]] (AppE (AppE (ConE Person) (AppE (VarE fromSql) (VarE id))) (AppE (VarE fromSql) (VarE name)))
\ [ id, name ] -> ( ( Person ( fromSql id )) ( fromSql name ))
\ [ id, name ] -> Person $ fromSql id $ fromSql name
( Exp, runQ [| \[id,name] -> Person (fromSql id) (fromSql name) |] ghci!)
id name, , field_1 ..
makeMakeModel qFieldNames qMapFunction qConstructor = -- ["id","name"] 'fromSql 'Person
LamE [ListP (map VarP qFieldNames)] -- \ [id,name]
$ foldl AppE (ConE qConstructor) -- Person
[AppE (VarE qMapFunction) (VarE name)|name <- qFieldNames]
-- $ id $ name
makeModel fieldNames mapFunction constructor = do
names <- mapM newName fieldNames
return $ makeMakeModel names mapFunction constructor
ghci -XTemplateHaskell:
*Main> runQ $ makeModel ["id","name"] 'fromSql 'Person
LamE [ListP [VarP id_0,VarP name_1]] (AppE (AppE (ConE Main.Person) (AppE (VarE Main.fromSql) (VarE id_0))) (AppE (VarE Main.fromSql) (VarE name_1)))
*Main> $(makeModel ["id","name"] 'fromSql 'Person) ["1234","James"]
Person 1234 "James"
, , newName, , , , , 'fromSql 'Person .
,
runQ [d| makeModel [id,name] = Person (fromSql id) (fromSql name) |]
- [d| ... |] .