Skip to content

Instantly share code, notes, and snippets.

@worldsayshi
Last active August 29, 2015 14:07
Show Gist options
  • Save worldsayshi/afe2dda684f76cf784cf to your computer and use it in GitHub Desktop.
Save worldsayshi/afe2dda684f76cf784cf to your computer and use it in GitHub Desktop.
Hello world inspection of haskell data types with template haskell
{-# LANGUAGE TemplateHaskell #-}
module Templ1 where
import Language.Haskell.TH
import Templ2
data Person = P {
name :: String,
age :: Integer
}
thisIsData = $(whatIs ''Person)
thisIsConstr = $(whatIs 'P)
main = putStr $(inspData ''Person)
{-# LANGUAGE TemplateHaskell #-}
module Templ2 where
import Language.Haskell.TH
import Data.List
-- useful sources:
-- https://hackage.haskell.org/package/template-haskell-2.8.0.0/docs/Language-Haskell-TH.html
-- https://hackage.haskell.org/package/data-lens-template-2.1.3/docs/src/Data-Lens-Template.html#makeLenses
whatIs name = do
info <- reify name
case info of
(TyConI dec) -> litE $ StringL "Data Declaration"
(DataConI name typ parentName fixity) -> litE $ StringL "Type Constructor" -- $ show typ
_ -> fail ("Unsupported name: "++nameBase name)
inspData name = do
info <- reify name
inspInfo info
where
inspInfo info =
case info of
(TyConI dec) -> --litE $ StringL (show dec) --
inspDec dec
_ -> fail ("Unsupported name: "++nameBase name)
inspDec dec =
case dec of
(DataD _ name _ constrs _) -> litE $ StringL $
(unlines $ map
inspConstr constrs)
_ -> fail $ "Unsupported dec: "++(show dec)
inspConstr con =
case con of
(RecC name varStrictTypes)-> show name ++ " { " ++ (unlines $ intersperse ", " $ map inspVarStrTyp varStrictTypes) ++ " } "
_ -> fail $ "Unsupported record field"
inspVarStrTyp (v,_,t) = (nameBase v) ++ " :: " ++ show t
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment