-- |
-- Module      : Data.Express.Instances
-- Copyright   : (c) 2019-2021 Rudy Matela
-- License     : 3-Clause BSD  (see the file LICENSE)
-- Maintainer  : Rudy Matela <rudy@matela.com.br>
--
-- Defines utilities do deal with instances of typeclasses
--
-- Functions provided by this module store the set of instances as a simple
-- Haskell list.  When storing only a few instances this should be fine in
-- terms of performance.
--
-- If you plan to store hundreds or thousands of instances,
-- we recommend implementing different versions that use
-- a more efficient Set/Map storage.
module Data.Express.Instances
  ( reifyEq
  , reifyOrd
  , reifyEqOrd
  , reifyName

  , mkEq
  , mkOrd
  , mkOrdLessEqual
  , mkName
  , mkNameWith

  , isEq
  , isOrd
  , isEqOrd
  , isEqT
  , isOrdT
  , isEqOrdT

  , mkEquation
  , mkComparisonLE
  , mkComparisonLT
  , mkComparison
  , lookupComparison

  , listVarsWith
  , lookupName
  , lookupNames

  , validApps
  , findValidApp

  , preludeNameInstances
  )
where

import Data.Express.Basic
import Data.Express.Name
import Data.Express.Express
import Data.Express.Utils.Typeable
import Data.Express.Utils.List
import Data.Maybe
import Control.Applicative ((<$>)) -- for GHC <= 7.8


-- reifying instances --

-- | /O(1)./
-- Reifies an 'Eq' instance into a list of 'Expr's.
-- The list will contain '==' and '/=' for the given type.
-- (cf. 'mkEq', 'mkEquation')
--
-- > > reifyEq (undefined :: Int)
-- > [ (==) :: Int -> Int -> Bool
-- > , (/=) :: Int -> Int -> Bool ]
--
-- > > reifyEq (undefined :: Bool)
-- > [ (==) :: Bool -> Bool -> Bool
-- > , (/=) :: Bool -> Bool -> Bool ]
--
-- > > reifyEq (undefined :: String)
-- > [ (==) :: [Char] -> [Char] -> Bool
-- > , (/=) :: [Char] -> [Char] -> Bool ]
reifyEq :: (Typeable a, Eq a) => a -> [Expr]
reifyEq :: forall a. (Typeable a, Eq a) => a -> [Expr]
reifyEq a
a  =  forall a. Typeable a => (a -> a -> Bool) -> [Expr]
mkEq  (forall a. Eq a => a -> a -> Bool
(==) forall a b. (a -> b) -> a -> a -> b
-:> a
a)

-- | /O(1)./
-- Reifies an 'Ord' instance into a list of 'Expr's.
-- The list will contain 'compare', '<=' and '<' for the given type.
-- (cf. 'mkOrd', 'mkOrdLessEqual', 'mkComparisonLE', 'mkComparisonLT')
--
-- > > reifyOrd (undefined :: Int)
-- > [ (<=) :: Int -> Int -> Bool
-- > , (<) :: Int -> Int -> Bool ]
--
-- > > reifyOrd (undefined :: Bool)
-- > [ (<=) :: Bool -> Bool -> Bool
-- > , (<) :: Bool -> Bool -> Bool ]
--
-- > > reifyOrd (undefined :: [Bool])
-- > [ (<=) :: [Bool] -> [Bool] -> Bool
-- > , (<) :: [Bool] -> [Bool] -> Bool ]
reifyOrd :: (Typeable a, Ord a) => a -> [Expr]
reifyOrd :: forall a. (Typeable a, Ord a) => a -> [Expr]
reifyOrd a
a  =  forall a. Typeable a => (a -> a -> Ordering) -> [Expr]
mkOrd (forall a. Ord a => a -> a -> Ordering
compare forall a b. (a -> b) -> a -> a -> b
-:> a
a)

-- | /O(1)./
-- Reifies 'Eq' and 'Ord' instances into a list of 'Expr'.
reifyEqOrd :: (Typeable a, Ord a) => a -> [Expr]
reifyEqOrd :: forall a. (Typeable a, Ord a) => a -> [Expr]
reifyEqOrd a
a  =  forall a. (Typeable a, Eq a) => a -> [Expr]
reifyEq a
a forall a. [a] -> [a] -> [a]
++ forall a. (Typeable a, Ord a) => a -> [Expr]
reifyOrd a
a

-- | /O(1)./
-- Reifies a 'Name' instance into a list of 'Expr's.
-- The list will contain 'name' for the given type.
-- (cf. 'mkName', 'lookupName', 'lookupNames')
--
-- > > reifyName (undefined :: Int)
-- > [name :: Int -> [Char]]
--
-- > > reifyName (undefined :: Bool)
-- > [name :: Bool -> [Char]]
reifyName :: (Typeable a, Name a) => a -> [Expr]
reifyName :: forall a. (Typeable a, Name a) => a -> [Expr]
reifyName a
a  =  forall a. Typeable a => (a -> String) -> [Expr]
mkName (forall a. Name a => a -> String
name forall a b. (a -> b) -> a -> a -> b
-:> a
a)

-- | /O(1)/.
-- Builds a reified 'Eq' instance from the given '==' function.
-- (cf. 'reifyEq')
--
-- > > mkEq ((==) :: Int -> Int -> Bool)
-- > [ (==) :: Int -> Int -> Bool
-- > , (/=) :: Int -> Int -> Bool ]
mkEq :: Typeable a => (a -> a -> Bool) -> [Expr]
mkEq :: forall a. Typeable a => (a -> a -> Bool) -> [Expr]
mkEq a -> a -> Bool
(==)  =
  [ forall a. Typeable a => String -> a -> Expr
value String
"==" a -> a -> Bool
(==)
  , forall a. Typeable a => String -> a -> Expr
value String
"/=" a -> a -> Bool
(/=)
  ]
  where
  a
x /= :: a -> a -> Bool
/= a
y = Bool -> Bool
not (a
x a -> a -> Bool
== a
y)

-- | /O(1)/.
-- Builds a reified 'Ord' instance from the given 'compare' function.
-- (cf. 'reifyOrd', 'mkOrdLessEqual')
mkOrd :: Typeable a => (a -> a -> Ordering) -> [Expr]
mkOrd :: forall a. Typeable a => (a -> a -> Ordering) -> [Expr]
mkOrd a -> a -> Ordering
compare  =
  [ forall a. Typeable a => String -> a -> Expr
value String
"<=" a -> a -> Bool
(<=)
  , forall a. Typeable a => String -> a -> Expr
value String
"<" a -> a -> Bool
(<)
-- we don't include other Ord functions, at least for now
--, value "compare" compare
  ]
  where
  a
x < :: a -> a -> Bool
<  a
y  =  a
x a -> a -> Ordering
`compare` a
y forall a. Eq a => a -> a -> Bool
== Ordering
LT
  a
x <= :: a -> a -> Bool
<= a
y  =  a
x a -> a -> Ordering
`compare` a
y forall a. Eq a => a -> a -> Bool
/= Ordering
GT

-- | /O(1)/.
-- Builds a reified 'Ord' instance from the given '<=' function.
-- (cf. 'reifyOrd', 'mkOrd')
mkOrdLessEqual :: Typeable a => (a -> a -> Bool) -> [Expr]
mkOrdLessEqual :: forall a. Typeable a => (a -> a -> Bool) -> [Expr]
mkOrdLessEqual a -> a -> Bool
(<=)  =
  [ forall a. Typeable a => String -> a -> Expr
value String
"<=" a -> a -> Bool
(<=)
  , forall a. Typeable a => String -> a -> Expr
value String
"<" a -> a -> Bool
(<)
  ]
  where
  a
x < :: a -> a -> Bool
< a
y  =  Bool -> Bool
not (a
y a -> a -> Bool
<= a
x)

-- | /O(1)/.
-- Builds a reified 'Name' instance from the given 'name' function.
-- (cf. 'reifyName', 'mkNameWith')
mkName :: Typeable a => (a -> String) -> [Expr]
mkName :: forall a. Typeable a => (a -> String) -> [Expr]
mkName a -> String
name  =  [forall a. Typeable a => String -> a -> Expr
value String
"name" a -> String
name]

-- | /O(1)/.
-- Builds a reified 'Name' instance from the given 'String' and type.
-- (cf. 'reifyName', 'mkName')
mkNameWith :: Typeable a => String -> a -> [Expr]
mkNameWith :: forall a. Typeable a => String -> a -> [Expr]
mkNameWith String
n a
a  =  [forall a. Typeable a => String -> a -> Expr
value String
"name" (forall a b. a -> b -> a
const String
n forall a b. (a -> b) -> a -> a -> b
-:> a
a)]


-- searching for functions --

-- | /O(n)./
-- Lookups for a comparison function (@:: a -> a -> Bool@)
-- with the given name and argument type.
lookupComparison :: String -> TypeRep -> [Expr] -> Maybe Expr
lookupComparison :: String -> TypeRep -> [Expr] -> Maybe Expr
lookupComparison String
n' TypeRep
t  =  forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (\i :: Expr
i@(Value String
n Dynamic
_) -> String
n forall a. Eq a => a -> a -> Bool
== String
n' Bool -> Bool -> Bool
&& Expr -> TypeRep
typ Expr
i forall a. Eq a => a -> a -> Bool
== TypeRep -> TypeRep
mkComparisonTy TypeRep
t)

-- | /O(n)./
-- Returns whether an 'Eq' instance exists in the given instances list
-- for the given 'TypeRep'.
--
-- > > isEqT (reifyEqOrd (undefined :: Int)) (typeOf (undefined :: Int))
-- > True
--
-- > > isEqT (reifyEqOrd (undefined :: Int)) (typeOf (undefined :: [[[Int]]]))
-- > False
--
-- Given that the instances list has length /n/, this function is /O(n)/.
isEqT :: [Expr] -> TypeRep -> Bool
isEqT :: [Expr] -> TypeRep -> Bool
isEqT [Expr]
is TypeRep
t  =  forall a. Maybe a -> Bool
isJust forall a b. (a -> b) -> a -> b
$ String -> TypeRep -> [Expr] -> Maybe Expr
lookupComparison String
"==" TypeRep
t [Expr]
is

-- | /O(n)./
-- Returns whether an 'Ord' instance exists in the given instances list
-- for the given 'TypeRep'.
--
-- > > isOrdT (reifyEqOrd (undefined :: Int)) (typeOf (undefined :: Int))
-- > True
--
-- > > isOrdT (reifyEqOrd (undefined :: Int)) (typeOf (undefined :: [[[Int]]]))
-- > False
--
-- Given that the instances list has length /n/, this function is /O(n)/.
isOrdT :: [Expr] -> TypeRep -> Bool
isOrdT :: [Expr] -> TypeRep -> Bool
isOrdT [Expr]
is TypeRep
t  =  forall a. Maybe a -> Bool
isJust forall a b. (a -> b) -> a -> b
$ String -> TypeRep -> [Expr] -> Maybe Expr
lookupComparison String
"<=" TypeRep
t [Expr]
is

-- | /O(n)./
-- Returns whether both 'Eq' and 'Ord' instance exist in the given list
-- for the given 'TypeRep'.
--
-- Given that the instances list has length /n/, this function is /O(n)/.
isEqOrdT :: [Expr] -> TypeRep -> Bool
isEqOrdT :: [Expr] -> TypeRep -> Bool
isEqOrdT [Expr]
is TypeRep
t  =  [Expr] -> TypeRep -> Bool
isEqT [Expr]
is TypeRep
t Bool -> Bool -> Bool
&& [Expr] -> TypeRep -> Bool
isOrdT [Expr]
is TypeRep
t

-- | /O(n+m)./
-- Returns whether an 'Eq' instance exists in the given instances list
-- for the given 'Expr'.
--
-- > > isEq (reifyEqOrd (undefined :: Int)) (val (0::Int))
-- > True
--
-- > > isEq (reifyEqOrd (undefined :: Int)) (val ([[[0::Int]]]))
-- > False
--
-- Given that the instances list has length /m/
-- and that the given 'Expr' has size /n/,
-- this function is /O(n+m)/.
isEq :: [Expr] -> Expr -> Bool
isEq :: [Expr] -> Expr -> Bool
isEq [Expr]
is  =  [Expr] -> TypeRep -> Bool
isEqT [Expr]
is forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr -> TypeRep
typ

-- | /O(n+m)./
-- Returns whether an 'Ord' instance exists in the given instances list
-- for the given 'Expr'.
--
-- > > isOrd (reifyEqOrd (undefined :: Int)) (val (0::Int))
-- > True
--
-- > > isOrd (reifyEqOrd (undefined :: Int)) (val ([[[0::Int]]]))
-- > False
--
-- Given that the instances list has length /m/
-- and that the given 'Expr' has size /n/,
-- this function is /O(n+m)/.
isOrd :: [Expr] -> Expr -> Bool
isOrd :: [Expr] -> Expr -> Bool
isOrd [Expr]
is  =  [Expr] -> TypeRep -> Bool
isOrdT [Expr]
is forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr -> TypeRep
typ

-- | /O(n+m)./
-- Returns whether both 'Eq' and 'Ord' instance exist in the given list
-- for the given 'Expr'.
--
-- Given that the instances list has length /m/
-- and that the given 'Expr' has size /n/,
-- this function is /O(n+m)/.
isEqOrd :: [Expr] -> Expr -> Bool
isEqOrd :: [Expr] -> Expr -> Bool
isEqOrd [Expr]
is Expr
e  =  [Expr] -> Expr -> Bool
isEq [Expr]
is Expr
e Bool -> Bool -> Bool
&& [Expr] -> Expr -> Bool
isOrd [Expr]
is Expr
e

-- | /O(n+m)./
-- Like 'mkEquation', 'mkComparisonLE' and 'mkComparisonLT'
-- but allows providing the binary operator name.
--
-- When not possible, this function returns 'False' encoded as an 'Expr'.
mkComparison :: String -> [Expr] -> Expr -> Expr -> Expr
mkComparison :: String -> [Expr] -> Expr -> Expr -> Expr
mkComparison String
n' [Expr]
is Expr
e1 Expr
e2  =  forall a. a -> Maybe a -> a
fromMaybe (forall a. (Typeable a, Show a) => a -> Expr
val Bool
False) forall a b. (a -> b) -> a -> b
$ do
  Expr
e1e <- [Expr] -> Expr -> Maybe Expr
findValidApp [Expr]
os Expr
e1
  Expr
e1e Expr -> Expr -> Maybe Expr
$$ Expr
e2
  where
  os :: [Expr]
os = [Expr
eq | eq :: Expr
eq@(Value String
n Dynamic
_) <- [Expr]
is, String
n forall a. Eq a => a -> a -> Bool
== String
n']

-- | /O(n+m)./
-- Returns an equation between two expressions
-- given that it is possible to do so from '==' operators
-- given in the argument instances list.
--
-- When not possible, this function returns 'False' encoded as an 'Expr'.
mkEquation :: [Expr] -> Expr -> Expr -> Expr
mkEquation :: [Expr] -> Expr -> Expr -> Expr
mkEquation  =  String -> [Expr] -> Expr -> Expr -> Expr
mkComparison String
"=="

-- | /O(n+m)./
-- Returns a less-than inequation between two expressions
-- given that it is possible to do so from '<' operators
-- given in the argument instances list.
--
-- When not possible, this function returns 'False' encoded as an 'Expr'.
mkComparisonLT :: [Expr] -> Expr -> Expr -> Expr
mkComparisonLT :: [Expr] -> Expr -> Expr -> Expr
mkComparisonLT  =  String -> [Expr] -> Expr -> Expr -> Expr
mkComparison String
"<"

-- | /O(n+m)./
-- Returns a less-than-or-equal-to inequation between two expressions
-- given that it is possible to do so from '<=' operators
-- given in the argument instances list.
--
-- When not possible, this function returns 'False' encoded as an 'Expr'.
mkComparisonLE :: [Expr] -> Expr -> Expr -> Expr
mkComparisonLE :: [Expr] -> Expr -> Expr -> Expr
mkComparisonLE  =  String -> [Expr] -> Expr -> Expr -> Expr
mkComparison String
"<="

-- | /O(n+m)./
-- Like 'name' but lifted over an instance list and an 'Expr'.
--
-- > > lookupName preludeNameInstances (val False)
-- > "p"
--
-- > > lookupName preludeNameInstances (val (0::Int))
-- > "x"
--
-- This function defaults to @"x"@ when no appropriate 'name' is found.
--
-- > > lookupName [] (val False)
-- > "x"
lookupName :: [Expr] -> Expr -> String
lookupName :: [Expr] -> Expr -> String
lookupName [Expr]
is Expr
e  =  forall a. a -> Maybe a -> a
fromMaybe String
d forall a b. (a -> b) -> a -> b
$ forall a. Typeable a => a -> Expr -> a
eval String
"x" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Expr] -> Expr -> Maybe Expr
findValidApp [Expr]
es Expr
e
  where
  t :: TypeRep
t  =  Expr -> TypeRep
typ Expr
e
  d :: String
d | TypeRep -> Bool
isFunTy TypeRep
t  =  String
"f"
    | Bool
otherwise  =  Char
'x' forall a. a -> [a] -> [a]
: forall a. Int -> a -> [a]
replicate (TypeRep -> Int
countListTy TypeRep
t) Char
's'
  es :: [Expr]
es = [Expr
e | e :: Expr
e@(Value String
"name" Dynamic
_) <- [Expr]
is]

-- | /O(n+m)./
-- A mix between 'lookupName' and 'names':
-- this returns an infinite list of names
-- based on an instances list and an 'Expr'.
lookupNames :: [Expr] -> Expr -> [String]
lookupNames :: [Expr] -> Expr -> [String]
lookupNames [Expr]
is  =  String -> [String]
variableNamesFromTemplate forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Expr] -> Expr -> String
lookupName [Expr]
is

-- | /O(n+m)./
-- Like 'lookupNames' but returns a list of variables encoded as 'Expr's.
listVarsWith :: [Expr] -> Expr -> [Expr]
listVarsWith :: [Expr] -> Expr -> [Expr]
listVarsWith [Expr]
is Expr
e  =  [Expr] -> Expr -> String
lookupName [Expr]
is Expr
e String -> Expr -> [Expr]
`listVarsAsTypeOf` Expr
e


-- helpers --

-- |
-- Given a list of functional expressions and another expression,
-- returns a list of valid applications.
validApps :: [Expr] -> Expr -> [Expr]
validApps :: [Expr] -> Expr -> [Expr]
validApps [Expr]
es Expr
e  =  forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (Expr -> Expr -> Maybe Expr
$$ Expr
e) [Expr]
es

-- |
-- Like 'validApps' but returns a 'Maybe' value.
findValidApp :: [Expr] -> Expr -> Maybe Expr
findValidApp :: [Expr] -> Expr -> Maybe Expr
findValidApp [Expr]
es  =  forall a. [a] -> Maybe a
listToMaybe forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Expr] -> Expr -> [Expr]
validApps [Expr]
es

(-:>) :: (a -> b) -> a -> (a -> b)
-:> :: forall a b. (a -> b) -> a -> a -> b
(-:>)  =  forall a b. a -> b -> a
const
infixl 1 -:>


-- reified instances --

-- |
-- A list of reified 'Name' instances
-- for an arbitrary selection of types from the Haskell "Prelude".
preludeNameInstances :: [Expr]
preludeNameInstances :: [Expr]
preludeNameInstances = forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
  [ forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: ())
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Bool)
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Int)
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Integer)
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Char)
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Ordering)
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Rational)
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Float)
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Double)

  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: [()])
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: [Bool])
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: [Int])
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: [Integer])
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: [Char])
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: [Ordering])
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: [Rational])
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: [Float])
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: [Double])

  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Maybe ())
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Maybe Bool)
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Maybe Int)
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Maybe Integer)
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Maybe Char)
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Maybe Ordering)
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Maybe Rational)
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Maybe Float)
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Maybe Double)

  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: ((),()))
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: (Bool,Bool))
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: (Int,Int))
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: (Integer,Integer))
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: (Char,Char))
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: (Ordering,Ordering))
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: (Rational,Rational))
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: (Float,Float))
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: (Double,Double))

  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: () -> ())
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Bool -> Bool)
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Int -> Int)
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Integer -> Integer)
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Char -> Char)
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Ordering -> Ordering)
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Rational -> Rational)
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Float -> Float)
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Double -> Double)

  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: () -> () -> ())
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Bool -> Bool -> Bool)
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Int -> Int -> Int)
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Integer -> Integer -> Integer)
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Char -> Char -> Char)
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Ordering -> Ordering -> Ordering)
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Rational -> Rational -> Rational)
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Float -> Float -> Float)
  , forall a. (Typeable a, Name a) => a -> [Expr]
reifyName (forall a. a
u :: Double -> Double -> Double)
  ]
  where
  u :: a
  u :: forall a. a
u  =  forall a. HasCallStack => a
undefined