{-# LANGUAGE
    ScopedTypeVariables,
    FlexibleInstances
  #-}

-- | Parameter Name Lists
module Graphics.QML.Objects.ParamNames (
    ParamNames,
    paramNames,
    noNames,
    fstName,
    plusName,
    anonParams,
    AnonParams ()
) where

-- | Represents a list of parameter names. The number of names in the list is
-- statically encoded using the length of the function type held in the type
-- parameter @a@.
newtype ParamNames a = ParamNames ([String] -> [String])

instance Show (ParamNames a) where
   show :: ParamNames a -> String
show (ParamNames [String] -> [String]
nsFunc) =
       let showHead :: [a] -> ShowS
showHead [] = String -> ShowS
showString String
"noNames"
           showHead (a
n:[a]
ns) = String -> ShowS
showString String
"fstName " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> ShowS
forall a. Show a => a -> ShowS
shows a
n ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> ShowS
forall {a}. Show a => [a] -> ShowS
showTail [a]
ns
           showTail :: [a] -> ShowS
showTail [] = ShowS
forall a. a -> a
id
           showTail (a
n:[a]
ns) = String -> ShowS
showString String
" `plusName` " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> ShowS
forall a. Show a => a -> ShowS
shows a
n ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> ShowS
showTail [a]
ns
       in [String] -> ShowS
forall {a}. Show a => [a] -> ShowS
showHead ([String] -> [String]
nsFunc []) String
""

-- | Coverts a 'ParamNames' list to an ordinary list of strings.
paramNames :: ParamNames a -> [String]
paramNames :: forall a. ParamNames a -> [String]
paramNames (ParamNames [String] -> [String]
names) = [String] -> [String]
names []

-- | Adds one parameter name to a 'ParamNames' list.
plusName :: ParamNames a -> String -> ParamNames (String -> a)
plusName :: forall a. ParamNames a -> String -> ParamNames (String -> a)
plusName (ParamNames [String] -> [String]
ns) String
n = ([String] -> [String]) -> ParamNames (String -> a)
forall a. ([String] -> [String]) -> ParamNames a
ParamNames (([String] -> [String]) -> ParamNames (String -> a))
-> ([String] -> [String]) -> ParamNames (String -> a)
forall a b. (a -> b) -> a -> b
$ [String] -> [String]
ns ([String] -> [String])
-> ([String] -> [String]) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String
n:)

-- | An empty 'ParamNames' list.
noNames :: ParamNames ()
noNames :: ParamNames ()
noNames = ([String] -> [String]) -> ParamNames ()
forall a. ([String] -> [String]) -> ParamNames a
ParamNames [String] -> [String]
forall a. a -> a
id

-- | Produces a 'ParamNames' list with a single name.
fstName :: String -> ParamNames (String -> ())
fstName :: String -> ParamNames (String -> ())
fstName = (ParamNames ()
noNames `plusName`)

-- | Helper class for generating anonymous parameter lists.
class AnonParams a where
    anonParams_ :: ParamNames a

instance (AnonParams b) => AnonParams (String -> b) where
    anonParams_ :: ParamNames (String -> b)
anonParams_ = ParamNames b -> String -> ParamNames (String -> b)
forall a. ParamNames a -> String -> ParamNames (String -> a)
plusName (ParamNames b
forall a. AnonParams a => ParamNames a
anonParams_ :: ParamNames b) String
""

instance AnonParams () where
    anonParams_ :: ParamNames ()
anonParams_ = ParamNames ()
noNames

-- | Polymorphically produces 'ParamNames' lists of any length filled with
-- blank parameter names.
anonParams :: (AnonParams a) => ParamNames a
anonParams :: forall a. AnonParams a => ParamNames a
anonParams = ParamNames a
forall a. AnonParams a => ParamNames a
anonParams_