fpco-api-1.0.0: src/library/FP/API/TH.hs
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS -fno-warn-orphans #-}
-- | Macro for generating a function out of a command
-- constructor. Only a subset of the IDE commands are of interest for
-- editors and general public use, so we use this command, and we can
-- also write haddock documentation.
module FP.API.TH
(cmd
) where
import FP.API.Run
import FP.API.Types
import Data.Char
import Language.Haskell.TH
cmd :: Name -> Q [Dec]
cmd name = do
DataConI _name typ _ptyp _fixity <- reify name
return [FunD funName
[Clause [] (NormalB (stripIdeCommand typ)) []]]
where funName = mkName (decapitalize (nameBase name))
stripIdeCommand = go (1 :: Int) where
go i (AppT (AppT ArrowT _x) (ConT t))
| t == ''IdeCommand =
(AppE (VarE 'runCommand)
(foldl (\inner i' -> AppE inner (VarE (gensym i')))
(ConE name)
[1..i-1]))
go i (AppT _x y) = LamE [VarP (gensym i)] (go (i+1) y)
go _ _ = error "invalid IdeCommand constructor type"
gensym i = mkName ("x" ++ show i)
decapitalize :: String -> String
decapitalize [] = []
decapitalize (x:xs) = toLower x : xs