express-1.0.14: src/Data/Express/Name.hs
-- |
-- Module : Data.Express.Name
-- Copyright : (c) 2019-2024 Rudy Matela
-- License : 3-Clause BSD (see the file LICENSE)
-- Maintainer : Rudy Matela <rudy@matela.com.br>
--
-- Defines the 'Name' type class.
module Data.Express.Name
( Name (..)
, names
, variableNamesFromTemplate
)
where
import Data.Express.Utils.String
import Data.List
-- for instances:
import Data.Int
import Data.Word
import Data.Ratio
import Data.Complex
import Data.Char
-- |
-- If we were to come up with a variable name for the given type
-- what 'name' would it be?
--
-- An instance for a given type @ Ty @ is simply given by:
--
-- > instance Name Ty where name _ = "x"
--
-- Examples:
--
-- > > name (undefined :: Int)
-- > "x"
--
-- > > name (undefined :: Bool)
-- > "p"
--
-- > > name (undefined :: [Int])
-- > "xs"
--
-- This is then used to generate an infinite list of variable 'names':
--
-- > > names (undefined :: Int)
-- > ["x", "y", "z", "x'", "y'", "z'", "x''", "y''", "z''", ...]
--
-- > > names (undefined :: Bool)
-- > ["p", "q", "r", "p'", "q'", "r'", "p''", "q''", "r''", ...]
--
-- > > names (undefined :: [Int])
-- > ["xs", "ys", "zs", "xs'", "ys'", "zs'", "xs''", "ys''", ...]
class Name a where
-- | /O(1)./
--
-- Returns a name for a variable of the given argument's type.
--
-- > > name (undefined :: Int)
-- > "x"
--
-- > > name (undefined :: [Bool])
-- > "ps"
--
-- > > name (undefined :: [Maybe Integer])
-- > "mxs"
--
-- The default definition is:
--
-- > name _ = "x"
name :: a -> String
name _ = "x"
-- |
-- > name (undefined :: ()) = "u"
-- > names (undefined :: ()) = ["u", "v", "w", "u'", "v'", ...]
instance Name () where name _ = "u"
-- |
-- > name (undefined :: Bool) = "p"
-- > names (undefined :: Bool) = ["p", "q", "r", "p'", "q'", ...]
instance Name Bool where name _ = "p"
-- |
-- > name (undefined :: Int) = "x"
-- > names (undefined :: Int) = ["x", "y", "z", "x'", "y'", ...]
instance Name Int where name _ = "x"
-- |
-- > name (undefined :: Integer) = "x"
-- > names (undefined :: Integer) = ["x", "y", "z", "x'", ...]
instance Name Integer where name _ = "x"
-- |
-- > name (undefined :: Char) = "c"
-- > names (undefined :: Char) = ["c", "d", "e", "c'", "d'", ...]
instance Name Char where name _ = "c"
-- |
-- > name (undefined :: Ordering) = "o"
-- > names (undefined :: Ordering) = ["o", "p", "q", "o'", ...]
instance Name Ordering where name _ = "o"
-- |
-- > name (undefined :: Rational) = "q"
-- > names (undefined :: Rational) = ["q", "r", "s", "q'", ...]
instance Name (Ratio a) where name _ = "q"
-- |
-- > name (undefined :: Complex) = "x"
-- > names (undefined :: Complex) = ["x", "y", "z", "x'", ...]
instance Name (Complex a) where name _ = "x"
-- |
-- > name (undefined :: Float) = "x"
-- > names (undefined :: Float) = ["x", "y", "z", "x'", ...]
instance Name Float where name _ = "x"
-- |
-- > name (undefined :: Double) = "x"
-- > names (undefined :: Double) = ["x", "y", "z", "x'", ...]
instance Name Double where name _ = "x"
-- |
-- > names (undefined :: ()->()) = ["f", "g", "h", "f'", ...]
-- > names (undefined :: Int->Int) = ["f", "g", "h", ...]
instance Name (a -> b) where name _ = "f"
-- |
-- > names (undefined :: Maybe Int) = ["mx", "mx1", "mx2", ...]
-- > nemes (undefined :: Maybe Bool) = ["mp", "mp1", "mp2", ...]
instance Name a => Name (Maybe a) where
name mx = "m" ++ name x
where
Just x = mx
-- |
-- > names (undefined :: Either Int Int) = ["exy", "exy1", ...]
-- > names (undefined :: Either Int Bool) = ["exp", "exp1", ...]
instance (Name a, Name b) => Name (Either a b) where
name exy = "e" ++ n ++ m
where
Left x = exy
Right y = exy
n = name x
(m:_) = delete n $ names y
-- |
-- > names (undefined :: (Int,Int)) = ["xy", "zw", "xy'", ...]
-- > names (undefined :: (Bool,Bool)) = ["pq", "rs", "pq'", ...]
instance (Name a, Name b) => Name (a,b) where
name xy = n ++ m
where
(x,y) = xy
n = name x
(m:_) = delete n $ names y
-- |
-- > names (undefined :: (Int,Int,Int)) = ["xyz","uvw", ...]
-- > names (undefined :: (Int,Bool,Char)) = ["xpc", "xpc1", ...]
instance (Name a, Name b, Name c) => Name (a,b,c) where
name xyz = n ++ m ++ o
where
(x,y,z) = xyz
n = name x
(m:_) = names y \\ [n]
(o:_) = names z \\ [n,m]
-- |
-- > names (undefined :: ((),(),(),())) = ["uuuu", "uuuu1", ...]
-- > names (undefined :: (Int,Int,Int,Int)) = ["xxxx", ...]
instance (Name a, Name b, Name c, Name d) => Name (a,b,c,d) where
name xyzw = name x ++ name y ++ name z ++ name w where (x,y,z,w) = xyzw
-- |
-- > names (undefined :: [Int]) = ["xs", "ys", "zs", "xs'", ...]
-- > names (undefined :: [Bool]) = ["ps", "qs", "rs", "ps'", ...]
instance Name a => Name [a] where
name xs = name x ++ "s" where (x:_) = xs
-- |
-- Returns na infinite list of variable names from the given type:
-- the result of 'variableNamesFromTemplate' after 'name'.
--
-- > > names (undefined :: Int)
-- > ["x", "y", "z", "x'", "y'", "z'", "x''", "y''", "z''", ...]
--
-- > > names (undefined :: Bool)
-- > ["p", "q", "r", "p'", "q'", "r'", "p''", "q''", "r''", ...]
--
-- > > names (undefined :: [Int])
-- > ["xs", "ys", "zs", "xs'", "ys'", "zs'", "xs''", "ys''", ...]
names :: Name a => a -> [String]
names = variableNamesFromTemplate . name
-- instances of further types and arities --
instance Name Word where name _ = "x"
instance Name Int8 where name _ = "x"
instance Name Int16 where name _ = "x"
instance Name Int32 where name _ = "x"
instance Name Int64 where name _ = "x"
instance Name Word8 where name _ = "x"
instance Name Word16 where name _ = "x"
instance Name Word32 where name _ = "x"
instance Name Word64 where name _ = "x"
instance Name GeneralCategory where name _ = "c"
instance (Name a, Name b, Name c, Name d, Name e) => Name (a,b,c,d,e) where
name xyzwv = name x ++ name y ++ name z ++ name w ++ name v
where (x,y,z,w,v) = xyzwv
instance (Name a, Name b, Name c, Name d, Name e, Name f)
=> Name (a,b,c,d,e,f) where
name xyzwvu = name x ++ name y ++ name z ++ name w ++ name v ++ name u
where (x,y,z,w,v,u) = xyzwvu
instance (Name a, Name b, Name c, Name d, Name e, Name f, Name g)
=> Name (a,b,c,d,e,f,g) where
name xyzwvut = name x ++ name y ++ name z ++ name w
++ name v ++ name u ++ name t
where (x,y,z,w,v,u,t) = xyzwvut
instance (Name a, Name b, Name c, Name d, Name e, Name f, Name g, Name h)
=> Name (a,b,c,d,e,f,g,h) where
name xyzwvuts = name x ++ name y ++ name z ++ name w
++ name v ++ name u ++ name t ++ name s
where (x,y,z,w,v,u,t,s) = xyzwvuts
instance ( Name a, Name b, Name c, Name d
, Name e, Name f, Name g, Name h
, Name i)
=> Name (a,b,c,d,e,f,g,h,i) where
name xyzwvutsr = name x ++ name y ++ name z ++ name w
++ name v ++ name u ++ name t ++ name s
++ name r
where (x,y,z,w,v,u,t,s,r) = xyzwvutsr
instance ( Name a, Name b, Name c, Name d
, Name e, Name f, Name g, Name h
, Name i, Name j )
=> Name (a,b,c,d,e,f,g,h,i,j) where
name xyzwvutsrq = name x ++ name y ++ name z ++ name w
++ name v ++ name u ++ name t ++ name s
++ name r ++ name q
where (x,y,z,w,v,u,t,s,r,q) = xyzwvutsrq
instance ( Name a, Name b, Name c, Name d
, Name e, Name f, Name g, Name h
, Name i, Name j, Name k )
=> Name (a,b,c,d,e,f,g,h,i,j,k) where
name xyzwvutsrqp = name x ++ name y ++ name z ++ name w
++ name v ++ name u ++ name t ++ name s
++ name r ++ name q ++ name p
where (x,y,z,w,v,u,t,s,r,q,p) = xyzwvutsrqp
instance ( Name a, Name b, Name c, Name d
, Name e, Name f, Name g, Name h
, Name i, Name j, Name k, Name l )
=> Name (a,b,c,d,e,f,g,h,i,j,k,l) where
name xyzwvutsrqpo = name x ++ name y ++ name z ++ name w
++ name v ++ name u ++ name t ++ name s
++ name r ++ name q ++ name p ++ name o
where (x,y,z,w,v,u,t,s,r,q,p,o) = xyzwvutsrqpo