module Data.Express.Utils.Typeable
( tyArity
, unFunTy
, isFunTy
, argumentTy
, resultTy
, finalResultTy
, boolTy
, intTy
, orderingTy
, mkComparisonTy
, mkCompareTy
, funTyCon
, compareTy
, elementTy
, typesIn
, typesInList
, countListTy
, (->::)
, module Data.Typeable
)
where
import Data.Typeable
import Data.Express.Utils
compareTy :: TypeRep -> TypeRep -> Ordering
compareTy :: TypeRep -> TypeRep -> Ordering
compareTy TypeRep
t1 TypeRep
t2 | TypeRep
t1 forall a. Eq a => a -> a -> Bool
== TypeRep
t2 = Ordering
EQ
compareTy TypeRep
t1 TypeRep
t2 = TypeRep -> Int
tyArity TypeRep
t1 forall a. Ord a => a -> a -> Ordering
`compare` TypeRep -> Int
tyArity TypeRep
t2
forall a. Semigroup a => a -> a -> a
<> forall (t :: * -> *) a. Foldable t => t a -> Int
length [TypeRep]
ts1 forall a. Ord a => a -> a -> Ordering
`compare` forall (t :: * -> *) a. Foldable t => t a -> Int
length [TypeRep]
ts2
forall a. Semigroup a => a -> a -> a
<> TyCon -> String
showTyCon TyCon
c1 forall a. Ord a => a -> a -> Ordering
`compare` TyCon -> String
showTyCon TyCon
c2
forall a. Semigroup a => a -> a -> a
<> forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr forall a. Semigroup a => a -> a -> a
(<>) Ordering
EQ (forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith TypeRep -> TypeRep -> Ordering
compareTy [TypeRep]
ts1 [TypeRep]
ts2)
where
(TyCon
c1,[TypeRep]
ts1) = TypeRep -> (TyCon, [TypeRep])
splitTyConApp TypeRep
t1
(TyCon
c2,[TypeRep]
ts2) = TypeRep -> (TyCon, [TypeRep])
splitTyConApp TypeRep
t2
showTyCon :: TyCon -> String
showTyCon :: TyCon -> String
showTyCon TyCon
con
| TyCon
con forall a. Eq a => a -> a -> Bool
== TyCon
listTyCon = String
"[]"
| Bool
otherwise = forall a. Show a => a -> String
show TyCon
con
tyArity :: TypeRep -> Int
tyArity :: TypeRep -> Int
tyArity TypeRep
t
| TypeRep -> Bool
isFunTy TypeRep
t = Int
1 forall a. Num a => a -> a -> a
+ TypeRep -> Int
tyArity (TypeRep -> TypeRep
resultTy TypeRep
t)
| Bool
otherwise = Int
0
finalResultTy :: TypeRep -> TypeRep
finalResultTy :: TypeRep -> TypeRep
finalResultTy TypeRep
t
| TypeRep -> Bool
isFunTy TypeRep
t = TypeRep -> TypeRep
finalResultTy (TypeRep -> TypeRep
resultTy TypeRep
t)
| Bool
otherwise = TypeRep
t
unFunTy :: TypeRep -> (TypeRep,TypeRep)
unFunTy :: TypeRep -> (TypeRep, TypeRep)
unFunTy TypeRep
t
| TypeRep -> Bool
isFunTy TypeRep
t = let (TyCon
f,[TypeRep
a,TypeRep
b]) = TypeRep -> (TyCon, [TypeRep])
splitTyConApp TypeRep
t in (TypeRep
a,TypeRep
b)
| Bool
otherwise = forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"error (unFunTy): `" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show TypeRep
t forall a. [a] -> [a] -> [a]
++ String
"` is not a function type"
argumentTy :: TypeRep -> TypeRep
argumentTy :: TypeRep -> TypeRep
argumentTy = forall a b. (a, b) -> a
fst forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeRep -> (TypeRep, TypeRep)
unFunTy
resultTy :: TypeRep -> TypeRep
resultTy :: TypeRep -> TypeRep
resultTy = forall a b. (a, b) -> b
snd forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeRep -> (TypeRep, TypeRep)
unFunTy
elementTy :: TypeRep -> TypeRep
elementTy :: TypeRep -> TypeRep
elementTy TypeRep
t
| TypeRep -> Bool
isListTy TypeRep
t = let (TyCon
_,[TypeRep
a]) = TypeRep -> (TyCon, [TypeRep])
splitTyConApp TypeRep
t in TypeRep
a
| Bool
otherwise = forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"error (elementTy): `" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show TypeRep
t forall a. [a] -> [a] -> [a]
++ String
"' is not a list type"
boolTy :: TypeRep
boolTy :: TypeRep
boolTy = forall a. Typeable a => a -> TypeRep
typeOf (forall a. HasCallStack => a
undefined :: Bool)
intTy :: TypeRep
intTy :: TypeRep
intTy = forall a. Typeable a => a -> TypeRep
typeOf (forall a. HasCallStack => a
undefined :: Int)
orderingTy :: TypeRep
orderingTy :: TypeRep
orderingTy = forall a. Typeable a => a -> TypeRep
typeOf (forall a. HasCallStack => a
undefined :: Ordering)
funTyCon :: TyCon
funTyCon :: TyCon
funTyCon = TypeRep -> TyCon
typeRepTyCon forall a b. (a -> b) -> a -> b
$ forall a. Typeable a => a -> TypeRep
typeOf (forall a. HasCallStack => a
undefined :: () -> ())
listTyCon :: TyCon
listTyCon :: TyCon
listTyCon = TypeRep -> TyCon
typeRepTyCon forall a b. (a -> b) -> a -> b
$ forall a. Typeable a => a -> TypeRep
typeOf (forall a. HasCallStack => a
undefined :: [()])
isFunTy :: TypeRep -> Bool
isFunTy :: TypeRep -> Bool
isFunTy TypeRep
t =
case TypeRep -> (TyCon, [TypeRep])
splitTyConApp TypeRep
t of
(TyCon
con,[TypeRep
_,TypeRep
_]) | TyCon
con forall a. Eq a => a -> a -> Bool
== TyCon
funTyCon -> Bool
True
(TyCon, [TypeRep])
_ -> Bool
False
isListTy :: TypeRep -> Bool
isListTy :: TypeRep -> Bool
isListTy TypeRep
t = case TypeRep -> (TyCon, [TypeRep])
splitTyConApp TypeRep
t of
(TyCon
con,[TypeRep
_]) | TyCon
con forall a. Eq a => a -> a -> Bool
== TyCon
listTyCon -> Bool
True
(TyCon, [TypeRep])
_ -> Bool
False
countListTy :: TypeRep -> Int
countListTy :: TypeRep -> Int
countListTy TypeRep
t = case TypeRep -> (TyCon, [TypeRep])
splitTyConApp TypeRep
t of
(TyCon
con,[TypeRep
t']) | TyCon
con forall a. Eq a => a -> a -> Bool
== TyCon
listTyCon -> Int
1 forall a. Num a => a -> a -> a
+ TypeRep -> Int
countListTy TypeRep
t'
(TyCon, [TypeRep])
_ -> Int
0
mkComparisonTy :: TypeRep -> TypeRep
mkComparisonTy :: TypeRep -> TypeRep
mkComparisonTy TypeRep
a = TypeRep
a TypeRep -> TypeRep -> TypeRep
->:: TypeRep
a TypeRep -> TypeRep -> TypeRep
->:: TypeRep
boolTy
mkCompareTy :: TypeRep -> TypeRep
mkCompareTy :: TypeRep -> TypeRep
mkCompareTy TypeRep
a = TypeRep
a TypeRep -> TypeRep -> TypeRep
->:: TypeRep
a TypeRep -> TypeRep -> TypeRep
->:: TypeRep
orderingTy
typesIn :: TypeRep -> [TypeRep]
typesIn :: TypeRep -> [TypeRep]
typesIn TypeRep
t = [TypeRep] -> [TypeRep]
typesInList [TypeRep
t]
typesInList :: [TypeRep] -> [TypeRep]
typesInList :: [TypeRep] -> [TypeRep]
typesInList [TypeRep]
ts = forall a. (a -> a -> Ordering) -> [a] -> [a]
nubSortBy TypeRep -> TypeRep -> Ordering
compareTy forall a b. (a -> b) -> a -> b
$ [TypeRep] -> [TypeRep] -> [TypeRep]
tins [TypeRep]
ts []
where
tin :: TypeRep -> [TypeRep] -> [TypeRep]
tin TypeRep
t = (TypeRep
tforall a. a -> [a] -> [a]
:) forall b c a. (b -> c) -> (a -> b) -> a -> c
. [TypeRep] -> [TypeRep] -> [TypeRep]
tins (TypeRep -> [TypeRep]
typeRepArgs TypeRep
t)
tins :: [TypeRep] -> [TypeRep] -> [TypeRep]
tins [TypeRep]
ts = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr forall b c a. (b -> c) -> (a -> b) -> a -> c
(.) forall a. a -> a
id (forall a b. (a -> b) -> [a] -> [b]
map TypeRep -> [TypeRep] -> [TypeRep]
tin [TypeRep]
ts)
(->::) :: TypeRep -> TypeRep -> TypeRep
->:: :: TypeRep -> TypeRep -> TypeRep
(->::) = TypeRep -> TypeRep -> TypeRep
mkFunTy
infixr 9 ->::