{-# LANGUAGE TemplateHaskell, CPP #-}
module Data.Express.Name.Derive
( deriveName
, deriveNameCascading
, deriveNameIfNeeded
)
where
import qualified Data.Express.Name as N
import Control.Monad
import Data.Char
import Data.List
import Data.Express.Utils.TH
deriveName :: Name -> DecsQ
deriveName :: Name -> DecsQ
deriveName = Name -> (Name -> DecsQ) -> Name -> DecsQ
deriveWhenNeededOrWarn ''N.Name Name -> DecsQ
reallyDeriveName
deriveNameIfNeeded :: Name -> DecsQ
deriveNameIfNeeded :: Name -> DecsQ
deriveNameIfNeeded = Name -> (Name -> DecsQ) -> Name -> DecsQ
deriveWhenNeeded ''N.Name Name -> DecsQ
reallyDeriveName
deriveNameCascading :: Name -> DecsQ
deriveNameCascading :: Name -> DecsQ
deriveNameCascading = Name -> (Name -> DecsQ) -> Name -> DecsQ
deriveWhenNeeded ''N.Name Name -> DecsQ
reallyDeriveNameCascading
reallyDeriveName :: Name -> DecsQ
reallyDeriveName :: Name -> DecsQ
reallyDeriveName Name
t = do
(Type
nt,[Type]
vs) <- Name -> Q (Type, [Type])
normalizeType Name
t
Bool
isNum <- Name
t Name -> Name -> Q Bool
`isInstanceOf` ''Num
[d| instance N.Name $(return nt) where
name _ = $(stringE $ vname isNum) |]
where
showJustName :: Name -> [Char]
showJustName = forall a. [a] -> [a]
reverse forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
takeWhile (forall a. Eq a => a -> a -> Bool
/= Char
'.') forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> [a]
reverse forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> [Char]
show
vname :: Bool -> [Char]
vname Bool
True = [Char]
"x"
vname Bool
False = forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Int -> [a] -> [a]
take Int
1 forall a b. (a -> b) -> a -> b
$ Name -> [Char]
showJustName Name
t
reallyDeriveNameCascading :: Name -> DecsQ
reallyDeriveNameCascading :: Name -> DecsQ
reallyDeriveNameCascading = Name -> (Name -> DecsQ) -> Name -> DecsQ
reallyDeriveCascading ''N.Name Name -> DecsQ
reallyDeriveName