{-# LANGUAGE CPP #-}
#if __GLASGOW_HASKELL__ == 708
{-# LANGUAGE DeriveDataTypeable, StandaloneDeriving #-}
#endif
module Data.Express.Core
(
Expr (..)
, value
, val
, ($$)
, var
, evaluate
, eval
, evl
, typ
, etyp
, mtyp
, toDynamic
, isValue
, isApp
, isVar
, isConst
, isIllTyped
, isWellTyped
, isFun
, hasVar
, isGround
, compareComplexity
, compareLexicographically
, compareQuickly
, arity
, size
, depth
, height
, subexprs
, values
, vars
, consts
, nubSubexprs
, nubValues
, nubVars
, nubConsts
, unfoldApp
, showExpr
, showOpExpr
, showPrecExpr
)
where
import Data.Dynamic
import Data.Express.Utils
import Data.Express.Utils.Typeable
data Expr = Value String Dynamic
| Expr :$ Expr
#if __GLASGOW_HASKELL__ == 708
deriving instance Typeable Expr
#endif
value :: Typeable a => String -> a -> Expr
value :: String -> a -> Expr
value String
s a
x = String -> Dynamic -> Expr
Value String
s (a -> Dynamic
forall a. Typeable a => a -> Dynamic
toDyn a
x)
val :: (Typeable a, Show a) => a -> Expr
val :: a -> Expr
val a
x = String -> a -> Expr
forall a. Typeable a => String -> a -> Expr
value (a -> String
forall a. Show a => a -> String
show a
x) a
x
($$) :: Expr -> Expr -> Maybe Expr
Expr
e1 $$ :: Expr -> Expr -> Maybe Expr
$$ Expr
e2 | Expr -> Bool
isIllTyped Expr
e = Maybe Expr
forall a. Maybe a
Nothing
| Bool
otherwise = Expr -> Maybe Expr
forall a. a -> Maybe a
Just Expr
e
where
e :: Expr
e = Expr
e1 Expr -> Expr -> Expr
:$ Expr
e2
var :: Typeable a => String -> a -> Expr
var :: String -> a -> Expr
var String
s a
a = String -> a -> Expr
forall a. Typeable a => String -> a -> Expr
value (Char
'_'Char -> String -> String
forall a. a -> [a] -> [a]
:String
s) (a
forall a. HasCallStack => a
undefined a -> a -> a
forall a. a -> a -> a
`asTypeOf` a
a)
typ :: Expr -> TypeRep
typ :: Expr -> TypeRep
typ = ((TypeRep, TypeRep) -> TypeRep)
-> (TypeRep -> TypeRep)
-> Either (TypeRep, TypeRep) TypeRep
-> TypeRep
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (TypeRep, TypeRep) -> TypeRep
forall a a a. (Show a, Show a) => (a, a) -> a
err TypeRep -> TypeRep
forall a. a -> a
id (Either (TypeRep, TypeRep) TypeRep -> TypeRep)
-> (Expr -> Either (TypeRep, TypeRep) TypeRep) -> Expr -> TypeRep
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr -> Either (TypeRep, TypeRep) TypeRep
etyp
where
err :: (a, a) -> a
err (a
t1, a
t2) = String -> a
forall a. HasCallStack => String -> a
error (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$ String
"type mismatch, cannot apply `"
String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
t1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' to `" String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
t2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"'"
etyp :: Expr -> Either (TypeRep, TypeRep) TypeRep
etyp :: Expr -> Either (TypeRep, TypeRep) TypeRep
etyp (Value String
_ Dynamic
d) = TypeRep -> Either (TypeRep, TypeRep) TypeRep
forall a b. b -> Either a b
Right (TypeRep -> Either (TypeRep, TypeRep) TypeRep)
-> TypeRep -> Either (TypeRep, TypeRep) TypeRep
forall a b. (a -> b) -> a -> b
$ Dynamic -> TypeRep
dynTypeRep Dynamic
d
etyp (Expr
e1 :$ Expr
e2) = case (Expr -> Either (TypeRep, TypeRep) TypeRep
etyp Expr
e1, Expr -> Either (TypeRep, TypeRep) TypeRep
etyp Expr
e2) of
(Right TypeRep
t1, Right TypeRep
t2) -> case TypeRep
t1 TypeRep -> TypeRep -> Maybe TypeRep
`funResultTy` TypeRep
t2 of
Maybe TypeRep
Nothing -> (TypeRep, TypeRep) -> Either (TypeRep, TypeRep) TypeRep
forall a b. a -> Either a b
Left (TypeRep
t1,TypeRep
t2)
Just TypeRep
t -> TypeRep -> Either (TypeRep, TypeRep) TypeRep
forall a b. b -> Either a b
Right TypeRep
t
(Left (TypeRep, TypeRep)
e, Either (TypeRep, TypeRep) TypeRep
_) -> (TypeRep, TypeRep) -> Either (TypeRep, TypeRep) TypeRep
forall a b. a -> Either a b
Left (TypeRep, TypeRep)
e
(Either (TypeRep, TypeRep) TypeRep
_, Left (TypeRep, TypeRep)
e) -> (TypeRep, TypeRep) -> Either (TypeRep, TypeRep) TypeRep
forall a b. a -> Either a b
Left (TypeRep, TypeRep)
e
mtyp :: Expr -> Maybe TypeRep
mtyp :: Expr -> Maybe TypeRep
mtyp = ((TypeRep, TypeRep) -> Maybe TypeRep)
-> (TypeRep -> Maybe TypeRep)
-> Either (TypeRep, TypeRep) TypeRep
-> Maybe TypeRep
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Maybe TypeRep -> (TypeRep, TypeRep) -> Maybe TypeRep
forall a b. a -> b -> a
const Maybe TypeRep
forall a. Maybe a
Nothing) TypeRep -> Maybe TypeRep
forall a. a -> Maybe a
Just (Either (TypeRep, TypeRep) TypeRep -> Maybe TypeRep)
-> (Expr -> Either (TypeRep, TypeRep) TypeRep)
-> Expr
-> Maybe TypeRep
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr -> Either (TypeRep, TypeRep) TypeRep
etyp
isIllTyped :: Expr -> Bool
isIllTyped :: Expr -> Bool
isIllTyped = Maybe TypeRep -> Bool
forall a. Maybe a -> Bool
isNothing (Maybe TypeRep -> Bool) -> (Expr -> Maybe TypeRep) -> Expr -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr -> Maybe TypeRep
mtyp
isWellTyped :: Expr -> Bool
isWellTyped :: Expr -> Bool
isWellTyped = Maybe TypeRep -> Bool
forall a. Maybe a -> Bool
isJust (Maybe TypeRep -> Bool) -> (Expr -> Maybe TypeRep) -> Expr -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr -> Maybe TypeRep
mtyp
isFun :: Expr -> Bool
isFun :: Expr -> Bool
isFun = TypeRep -> Bool
isFunTy (TypeRep -> Bool) -> (Expr -> TypeRep) -> Expr -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr -> TypeRep
typ
evaluate :: Typeable a => Expr -> Maybe a
evaluate :: Expr -> Maybe a
evaluate Expr
e = Expr -> Maybe Dynamic
toDynamic Expr
e Maybe Dynamic -> (Dynamic -> Maybe a) -> Maybe a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Dynamic -> Maybe a
forall a. Typeable a => Dynamic -> Maybe a
fromDynamic
eval :: Typeable a => a -> Expr -> a
eval :: a -> Expr -> a
eval a
x Expr
e = a -> Maybe a -> a
forall a. a -> Maybe a -> a
fromMaybe a
x (Expr -> Maybe a
forall a. Typeable a => Expr -> Maybe a
evaluate Expr
e)
evl :: Typeable a => Expr -> a
evl :: Expr -> a
evl Expr
e = a
r
where
r :: a
r = a -> Expr -> a
forall a. Typeable a => a -> Expr -> a
eval a
err Expr
e
err :: a
err = String -> a
forall a. HasCallStack => String -> a
error (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$ String
"evl: cannot evaluate Expr `" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Expr -> String
forall a. Show a => a -> String
show Expr
e String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' at the " String -> String -> String
forall a. [a] -> [a] -> [a]
++ TypeRep -> String
forall a. Show a => a -> String
show (a -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf a
r) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" type"
toDynamic :: Expr -> Maybe Dynamic
toDynamic :: Expr -> Maybe Dynamic
toDynamic (Value String
_ Dynamic
x) = Dynamic -> Maybe Dynamic
forall a. a -> Maybe a
Just Dynamic
x
toDynamic (Expr
e1 :$ Expr
e2) = do Dynamic
v1 <- Expr -> Maybe Dynamic
toDynamic Expr
e1
Dynamic
v2 <- Expr -> Maybe Dynamic
toDynamic Expr
e2
Dynamic -> Dynamic -> Maybe Dynamic
dynApply Dynamic
v1 Dynamic
v2
instance Show Expr where
showsPrec :: Int -> Expr -> String -> String
showsPrec Int
d Expr
e = Bool -> (String -> String) -> String -> String
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10)
((String -> String) -> String -> String)
-> (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ Int -> Expr -> String -> String
showsPrecExpr Int
0 Expr
e
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
" :: "
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr -> String -> String
showsTypeExpr Expr
e
showsTypeExpr :: Expr -> String -> String
showsTypeExpr :: Expr -> String -> String
showsTypeExpr Expr
e = case Expr -> Either (TypeRep, TypeRep) TypeRep
etyp Expr
e of
Left (TypeRep
t1,TypeRep
t2) -> String -> String -> String
showString String
"ill-typed # "
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeRep -> String -> String
forall a. Show a => a -> String -> String
shows TypeRep
t1
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
" $ "
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeRep -> String -> String
forall a. Show a => a -> String -> String
shows TypeRep
t2
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
" #"
Right TypeRep
t -> TypeRep -> String -> String
forall a. Show a => a -> String -> String
shows TypeRep
t
showsPrecExpr :: Int -> Expr -> String -> String
showsPrecExpr :: Int -> Expr -> String -> String
showsPrecExpr Int
d (Value String
"_" Dynamic
_) = String -> String -> String
showString String
"_"
showsPrecExpr Int
d (Value (Char
'_':String
s) Dynamic
_)
| String -> Bool
isInfixedPrefix String
s = String -> String -> String
showString (String -> String -> String) -> String -> String -> String
forall a b. (a -> b) -> a -> b
$ String -> String
toPrefix String
s
| Bool
otherwise = Bool -> (String -> String) -> String -> String
showParen (String -> Bool
isInfix String
s) ((String -> String) -> String -> String)
-> (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String -> String -> String
showString String
s
showsPrecExpr Int
d (Value String
s Dynamic
_) | String -> Bool
isInfixedPrefix String
s = String -> String -> String
showString (String -> String -> String) -> String -> String -> String
forall a b. (a -> b) -> a -> b
$ String -> String
toPrefix String
s
showsPrecExpr Int
d (Value String
s Dynamic
_) | String -> Bool
isNegativeLiteral String
s = Bool -> (String -> String) -> String -> String
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0) ((String -> String) -> String -> String)
-> (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String -> String -> String
showString String
s
showsPrecExpr Int
d (Value String
s Dynamic
_) = Bool -> (String -> String) -> String -> String
showParen Bool
sp ((String -> String) -> String -> String)
-> (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String -> String -> String
showString String
s
where sp :: Bool
sp = if String -> Bool
atomic String
s then String -> Bool
isInfix String
s else Bool -> (Int -> Bool) -> Maybe Int -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
True (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>) (Maybe Int -> Bool) -> Maybe Int -> Bool
forall a b. (a -> b) -> a -> b
$ String -> Maybe Int
outernmostPrec String
s
showsPrecExpr Int
d (Value String
":" Dynamic
_ :$ Expr
e1 :$ Expr
e2)
| Expr -> Bool
isConst Expr
e1 Bool -> Bool -> Bool
&& Expr -> Maybe TypeRep
mtyp Expr
e1 Maybe TypeRep -> Maybe TypeRep -> Bool
forall a. Eq a => a -> a -> Bool
== TypeRep -> Maybe TypeRep
forall a. a -> Maybe a
Just (Char -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf (Char
forall a. HasCallStack => a
undefined :: Char)) =
case Expr -> String -> String
showsTailExpr Expr
e2 String
"" of
Char
'\"':String
cs -> String -> String -> String
showString (String
"\"" String -> String -> String
forall a. [a] -> [a] -> [a]
++ (String -> String
forall a. [a] -> [a]
init (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
forall a. [a] -> [a]
tail) (Int -> Expr -> String -> String
showsPrecExpr Int
0 Expr
e1 String
"") String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
cs)
String
cs -> Bool -> (String -> String) -> String -> String
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> String -> Int
prec String
":")
((String -> String) -> String -> String)
-> (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String -> Expr -> String -> String
showsOpExpr String
":" Expr
e1 (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
":" (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
cs
showsPrecExpr Int
d (Value String
":" Dynamic
_ :$ Expr
e1 :$ Expr
e2) =
case Expr -> String -> String
showsTailExpr Expr
e2 String
"" of
String
"[]" -> String -> String -> String
showString String
"[" (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Expr -> String -> String
showsPrecExpr Int
0 Expr
e1 (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
"]"
Char
'[':String
cs -> String -> String -> String
showString String
"[" (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Expr -> String -> String
showsPrecExpr Int
0 Expr
e1 (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
"," (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
cs
String
cs -> Bool -> (String -> String) -> String -> String
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> String -> Int
prec String
":")
((String -> String) -> String -> String)
-> (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String -> Expr -> String -> String
showsOpExpr String
":" Expr
e1 (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
":" (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
cs
showsPrecExpr Int
d Expr
ee | Expr -> Bool
isTuple Expr
ee = Bool -> (String -> String) -> String -> String
showParen Bool
True
((String -> String) -> String -> String)
-> (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ ((String -> String) -> (String -> String) -> String -> String)
-> [String -> String] -> String -> String
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 (\String -> String
s1 String -> String
s2 -> String -> String
s1 (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
"," (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
s2)
(Int -> Expr -> String -> String
showsPrecExpr Int
0 (Expr -> String -> String) -> [Expr] -> [String -> String]
forall a b. (a -> b) -> [a] -> [b]
`map` Expr -> [Expr]
unfoldTuple Expr
ee)
showsPrecExpr Int
d (Value String
"if" Dynamic
_ :$ Expr
ep :$ Expr
ex :$ Expr
ey) =
Bool -> (String -> String) -> String -> String
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0) ((String -> String) -> String -> String)
-> (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String -> String -> String
showString String
"if " (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Expr -> String -> String
showsPrecExpr Int
0 Expr
ep
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
" then " (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Expr -> String -> String
showsPrecExpr Int
0 Expr
ex
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
" else " (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Expr -> String -> String
showsPrecExpr Int
0 Expr
ey
showsPrecExpr Int
d (Value String
"case" Dynamic
_ :$ Expr
ep :$ Expr
ex :$ Expr
ey) | Expr -> TypeRep
typ Expr
ep TypeRep -> TypeRep -> Bool
forall a. Eq a => a -> a -> Bool
== TypeRep
boolTy =
Bool -> (String -> String) -> String -> String
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0) ((String -> String) -> String -> String)
-> (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String -> String -> String
showString String
"case " (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Expr -> String -> String
showsPrecExpr Int
0 Expr
ep
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
" of False -> " (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Expr -> String -> String
showsPrecExpr Int
0 Expr
ex
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
"; True -> " (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Expr -> String -> String
showsPrecExpr Int
0 Expr
ey
showsPrecExpr Int
d (Value String
"case" Dynamic
_ :$ Expr
eo :$ Expr
ex :$ Expr
ey :$ Expr
ez) | Expr -> TypeRep
typ Expr
eo TypeRep -> TypeRep -> Bool
forall a. Eq a => a -> a -> Bool
== TypeRep
orderingTy =
Bool -> (String -> String) -> String -> String
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0) ((String -> String) -> String -> String)
-> (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String -> String -> String
showString String
"case " (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Expr -> String -> String
showsPrecExpr Int
0 Expr
eo
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
" of LT -> " (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Expr -> String -> String
showsPrecExpr Int
0 Expr
ex
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
"; EQ -> " (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Expr -> String -> String
showsPrecExpr Int
0 Expr
ey
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
"; GT -> " (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Expr -> String -> String
showsPrecExpr Int
0 Expr
ez
showsPrecExpr Int
d (Value String
",.." Dynamic
_ :$ Expr
ex :$ Expr
ey :$ Expr
ez) =
String -> String -> String
showString String
"[" (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Expr -> String -> String
showsPrecExpr Int
0 Expr
ex
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString (if Expr -> Bool
dotdot Expr
ex Bool -> Bool -> Bool
&& Expr -> Bool
dotdot Expr
ey Bool -> Bool -> Bool
&& Expr -> Bool
dotdot Expr
ez then String
"," else String
", ")
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Expr -> String -> String
showsPrecExpr Int
0 Expr
ey
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString (if Expr -> Bool
dotdot Expr
ex Bool -> Bool -> Bool
&& Expr -> Bool
dotdot Expr
ey Bool -> Bool -> Bool
&& Expr -> Bool
dotdot Expr
ez then String
".." else String
" .. ")
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Expr -> String -> String
showsPrecExpr Int
0 Expr
ez
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
"]"
showsPrecExpr Int
d (Value String
",.." Dynamic
_ :$ Expr
ex :$ Expr
ey) =
String -> String -> String
showString String
"[" (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Expr -> String -> String
showsPrecExpr Int
0 Expr
ex
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString (if Expr -> Bool
dotdot Expr
ex Bool -> Bool -> Bool
&& Expr -> Bool
dotdot Expr
ey then String
"," else String
", ")
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Expr -> String -> String
showsPrecExpr Int
0 Expr
ey
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString (if Expr -> Bool
dotdot Expr
ex Bool -> Bool -> Bool
&& Expr -> Bool
dotdot Expr
ey then String
"..]" else String
" ..]")
showsPrecExpr Int
d (Value String
".." Dynamic
_ :$ Expr
ex :$ Expr
ey) =
String -> String -> String
showString String
"[" (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Expr -> String -> String
showsPrecExpr Int
0 Expr
ex
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString (if Expr -> Bool
dotdot Expr
ex Bool -> Bool -> Bool
&& Expr -> Bool
dotdot Expr
ey then String
".." else String
" .. ")
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Expr -> String -> String
showsPrecExpr Int
0 Expr
ey
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
"]"
showsPrecExpr Int
d (Value String
".." Dynamic
_ :$ Expr
ex) =
String -> String -> String
showString String
"[" (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Expr -> String -> String
showsPrecExpr Int
0 Expr
ex (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString (if Expr -> Bool
dotdot Expr
ex then String
"..]" else String
" ..]")
showsPrecExpr Int
d (Value String
f' Dynamic
_ :$ Expr
e1 :$ Expr
e2)
| String -> Bool
isInfix String
f = Bool -> (String -> String) -> String -> String
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> String -> Int
prec String
f)
((String -> String) -> String -> String)
-> (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String -> Expr -> String -> String
showsOpExpr String
f Expr
e1
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
" " (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
f (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
" "
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Expr -> String -> String
showsOpExpr String
f Expr
e2
| Bool
otherwise = Bool -> (String -> String) -> String -> String
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> String -> Int
prec String
" ")
((String -> String) -> String -> String)
-> (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String -> String -> String
showString String
f
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
" " (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Expr -> String -> String
showsOpExpr String
" " Expr
e1
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
" " (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Expr -> String -> String
showsOpExpr String
" " Expr
e2
where
f :: String
f = case String
f' of String
"_" -> String
"_"
(Char
'_':String
f) -> String
f
String
f -> String
f
showsPrecExpr Int
d (Value String
f' Dynamic
_ :$ Expr
e1)
| String -> Bool
isInfix String
f = Bool -> (String -> String) -> String -> String
showParen Bool
True ((String -> String) -> String -> String)
-> (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String -> Expr -> String -> String
showsOpExpr String
f Expr
e1 (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
" " (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
f
where
f :: String
f = case String
f' of String
"_" -> String
"_"
(Char
'_':String
f) -> String
f
String
f -> String
f
showsPrecExpr Int
d (Expr
e1 :$ Expr
e2) = Bool -> (String -> String) -> String -> String
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> String -> Int
prec String
" ")
((String -> String) -> String -> String)
-> (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ Int -> Expr -> String -> String
showsPrecExpr (String -> Int
prec String
" ") Expr
e1
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
" "
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Expr -> String -> String
showsPrecExpr (String -> Int
prec String
" " Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Expr
e2
dotdot :: Expr -> Bool
dotdot :: Expr -> Bool
dotdot (Value (Char
c:String
_) Dynamic
_) = Char -> Bool
isNumber Char
c Bool -> Bool -> Bool
|| Char -> Bool
isLower Char
c Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'_' Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\''
dotdot Expr
_ = Bool
False
showsTailExpr :: Expr -> String -> String
showsTailExpr :: Expr -> String -> String
showsTailExpr (Value String
":" Dynamic
_ :$ Expr
e1 :$ Expr
e2)
| Expr -> Bool
isConst Expr
e1 Bool -> Bool -> Bool
&& Expr -> Maybe TypeRep
mtyp Expr
e1 Maybe TypeRep -> Maybe TypeRep -> Bool
forall a. Eq a => a -> a -> Bool
== TypeRep -> Maybe TypeRep
forall a. a -> Maybe a
Just (Char -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf (Char
forall a. HasCallStack => a
undefined :: Char)) =
case Int -> Expr -> String -> String
showsPrecExpr Int
0 Expr
e2 String
"" of
Char
'\"':String
cs -> String -> String -> String
showString (String
"\"" String -> String -> String
forall a. [a] -> [a] -> [a]
++ (String -> String
forall a. [a] -> [a]
init (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
forall a. [a] -> [a]
tail) (Int -> Expr -> String -> String
showsPrecExpr Int
0 Expr
e1 String
"") String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
cs)
String
cs -> String -> Expr -> String -> String
showsOpExpr String
":" Expr
e1 (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
":" (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr -> String -> String
showsTailExpr Expr
e2
showsTailExpr (Value String
":" Dynamic
_ :$ Expr
e1 :$ Expr
e2) =
case Int -> Expr -> String -> String
showsPrecExpr Int
0 Expr
e2 String
"" of
String
"[]" -> String -> String -> String
showString String
"[" (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Expr -> String -> String
showsPrecExpr Int
0 Expr
e1 (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
"]"
Char
'[':String
cs -> String -> String -> String
showString String
"[" (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Expr -> String -> String
showsPrecExpr Int
0 Expr
e1 (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
"," (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
cs
String
cs -> String -> Expr -> String -> String
showsOpExpr String
":" Expr
e1 (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
":" (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr -> String -> String
showsTailExpr Expr
e2
showsTailExpr Expr
e = String -> Expr -> String -> String
showsOpExpr String
":" Expr
e
showsOpExpr :: String -> Expr -> String -> String
showsOpExpr :: String -> Expr -> String -> String
showsOpExpr String
op = Int -> Expr -> String -> String
showsPrecExpr (String -> Int
prec String
op Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
showOpExpr :: String -> Expr -> String
showOpExpr :: String -> Expr -> String
showOpExpr String
op = Int -> Expr -> String
showPrecExpr (String -> Int
prec String
op Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
showPrecExpr :: Int -> Expr -> String
showPrecExpr :: Int -> Expr -> String
showPrecExpr Int
n Expr
e = Int -> Expr -> String -> String
showsPrecExpr Int
n Expr
e String
""
showExpr :: Expr -> String
showExpr :: Expr -> String
showExpr = Int -> Expr -> String
showPrecExpr (-Int
1)
instance Eq Expr where
Value String
s1 Dynamic
d1 == :: Expr -> Expr -> Bool
== Value String
s2 Dynamic
d2 = String
s1 String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
s2 Bool -> Bool -> Bool
&& Dynamic -> TypeRep
dynTypeRep Dynamic
d1 TypeRep -> TypeRep -> Bool
forall a. Eq a => a -> a -> Bool
== Dynamic -> TypeRep
dynTypeRep Dynamic
d2
(Expr
ef1 :$ Expr
ex1) == (Expr
ef2 :$ Expr
ex2) = Expr
ef1 Expr -> Expr -> Bool
forall a. Eq a => a -> a -> Bool
== Expr
ef2 Bool -> Bool -> Bool
&& Expr
ex1 Expr -> Expr -> Bool
forall a. Eq a => a -> a -> Bool
== Expr
ex2
Expr
_ == Expr
_ = Bool
False
instance Ord Expr where
compare :: Expr -> Expr -> Ordering
compare = Expr -> Expr -> Ordering
compareComplexity (Expr -> Expr -> Ordering)
-> (Expr -> Expr -> Ordering) -> Expr -> Expr -> Ordering
forall a. Semigroup a => a -> a -> a
<> Expr -> Expr -> Ordering
compareLexicographically
compareComplexity :: Expr -> Expr -> Ordering
compareComplexity :: Expr -> Expr -> Ordering
compareComplexity = (Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Int -> Int -> Ordering)
-> (Expr -> Int) -> Expr -> Expr -> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` [Expr] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([Expr] -> Int) -> (Expr -> [Expr]) -> Expr -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr -> [Expr]
values)
(Expr -> Expr -> Ordering)
-> (Expr -> Expr -> Ordering) -> Expr -> Expr -> Ordering
forall a. Semigroup a => a -> a -> a
<> ((Int -> Int -> Ordering) -> Int -> Int -> Ordering
forall a b c. (a -> b -> c) -> b -> a -> c
flip Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Int -> Int -> Ordering)
-> (Expr -> Int) -> Expr -> Expr -> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` [Expr] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([Expr] -> Int) -> (Expr -> [Expr]) -> Expr -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr -> [Expr]
nubVars)
(Expr -> Expr -> Ordering)
-> (Expr -> Expr -> Ordering) -> Expr -> Expr -> Ordering
forall a. Semigroup a => a -> a -> a
<> ((Int -> Int -> Ordering) -> Int -> Int -> Ordering
forall a b c. (a -> b -> c) -> b -> a -> c
flip Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Int -> Int -> Ordering)
-> (Expr -> Int) -> Expr -> Expr -> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` [Expr] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([Expr] -> Int) -> (Expr -> [Expr]) -> Expr -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr -> [Expr]
vars)
(Expr -> Expr -> Ordering)
-> (Expr -> Expr -> Ordering) -> Expr -> Expr -> Ordering
forall a. Semigroup a => a -> a -> a
<> (Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Int -> Int -> Ordering)
-> (Expr -> Int) -> Expr -> Expr -> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` [Expr] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([Expr] -> Int) -> (Expr -> [Expr]) -> Expr -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr -> [Expr]
nubConsts)
compareLexicographically :: Expr -> Expr -> Ordering
compareLexicographically :: Expr -> Expr -> Ordering
compareLexicographically = Expr -> Expr -> Ordering
cmp
where
(Expr
f :$ Expr
x) cmp :: Expr -> Expr -> Ordering
`cmp` (Expr
g :$ Expr
y) = Expr
f Expr -> Expr -> Ordering
`cmp` Expr
g Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> Expr
x Expr -> Expr -> Ordering
`cmp` Expr
y
(Expr
_ :$ Expr
_) `cmp` Expr
_ = Ordering
GT
Expr
_ `cmp` (Expr
_ :$ Expr
_) = Ordering
LT
e1 :: Expr
e1@(Value String
s1 Dynamic
_) `cmp` e2 :: Expr
e2@(Value String
s2 Dynamic
_) = Expr -> Bool
isConst Expr
e1 Bool -> Bool -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Expr -> Bool
isConst Expr
e2
Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> Expr -> TypeRep
typ Expr
e1 TypeRep -> TypeRep -> Ordering
`compareTy` Expr -> TypeRep
typ Expr
e2
Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> String
s1 String -> String -> Ordering
`cmpbool` String
s2
Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
s1 Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
s2
Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> String
s1 String -> String -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` String
s2
String
"False" cmpbool :: String -> String -> Ordering
`cmpbool` String
"True" = Ordering
LT
String
"True" `cmpbool` String
"False" = Ordering
GT
String
_ `cmpbool` String
_ = Ordering
EQ
compareQuickly :: Expr -> Expr -> Ordering
compareQuickly :: Expr -> Expr -> Ordering
compareQuickly = Expr -> Expr -> Ordering
cmp
where
(Expr
f :$ Expr
x) cmp :: Expr -> Expr -> Ordering
`cmp` (Expr
g :$ Expr
y) = Expr
f Expr -> Expr -> Ordering
`cmp` Expr
g Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> Expr
x Expr -> Expr -> Ordering
`cmp` Expr
y
(Expr
_ :$ Expr
_) `cmp` Expr
_ = Ordering
GT
Expr
_ `cmp` (Expr
_ :$ Expr
_) = Ordering
LT
x :: Expr
x@(Value String
n1 Dynamic
_) `cmp` y :: Expr
y@(Value String
n2 Dynamic
_) = Expr -> TypeRep
typ Expr
x TypeRep -> TypeRep -> Ordering
`compareTy` Expr -> TypeRep
typ Expr
y
Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> String
n1 String -> String -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` String
n2
unfoldApp :: Expr -> [Expr]
unfoldApp :: Expr -> [Expr]
unfoldApp Expr
e = Expr -> [Expr] -> [Expr]
u Expr
e []
where
u :: Expr -> [Expr] -> [Expr]
u (Expr
ef :$ Expr
ex) = Expr -> [Expr] -> [Expr]
u Expr
ef ([Expr] -> [Expr]) -> ([Expr] -> [Expr]) -> [Expr] -> [Expr]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Expr
exExpr -> [Expr] -> [Expr]
forall a. a -> [a] -> [a]
:)
u Expr
ex = (Expr
exExpr -> [Expr] -> [Expr]
forall a. a -> [a] -> [a]
:)
unfoldTuple :: Expr -> [Expr]
unfoldTuple :: Expr -> [Expr]
unfoldTuple = [Expr] -> [Expr]
u ([Expr] -> [Expr]) -> (Expr -> [Expr]) -> Expr -> [Expr]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr -> [Expr]
unfoldApp
where
u :: [Expr] -> [Expr]
u (Value String
cs Dynamic
_:[Expr]
es) | Bool -> Bool
not ([Expr] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Expr]
es) Bool -> Bool -> Bool
&& String
cs String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== Int -> Char -> String
forall a. Int -> a -> [a]
replicate ([Expr] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Expr]
es Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Char
',' = [Expr]
es
u [Expr]
_ = []
isTuple :: Expr -> Bool
isTuple :: Expr -> Bool
isTuple = Bool -> Bool
not (Bool -> Bool) -> (Expr -> Bool) -> Expr -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Expr] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([Expr] -> Bool) -> (Expr -> [Expr]) -> Expr -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr -> [Expr]
unfoldTuple
hasVar :: Expr -> Bool
hasVar :: Expr -> Bool
hasVar (Expr
e1 :$ Expr
e2) = Expr -> Bool
hasVar Expr
e1 Bool -> Bool -> Bool
|| Expr -> Bool
hasVar Expr
e2
hasVar Expr
e = Expr -> Bool
isVar Expr
e
isGround :: Expr -> Bool
isGround :: Expr -> Bool
isGround = Bool -> Bool
not (Bool -> Bool) -> (Expr -> Bool) -> Expr -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr -> Bool
hasVar
isConst :: Expr -> Bool
isConst :: Expr -> Bool
isConst (Value (Char
'_':String
_) Dynamic
_) = Bool
False
isConst (Value String
_ Dynamic
_) = Bool
True
isConst Expr
_ = Bool
False
isVar :: Expr -> Bool
isVar :: Expr -> Bool
isVar (Value (Char
'_':String
_) Dynamic
_) = Bool
True
isVar Expr
_ = Bool
False
isValue :: Expr -> Bool
isValue :: Expr -> Bool
isValue (Value String
_ Dynamic
_) = Bool
True
isValue Expr
_ = Bool
False
isApp :: Expr -> Bool
isApp :: Expr -> Bool
isApp (Expr
_ :$ Expr
_) = Bool
True
isApp Expr
_ = Bool
False
subexprs :: Expr -> [Expr]
subexprs :: Expr -> [Expr]
subexprs Expr
e = Expr -> [Expr] -> [Expr]
s Expr
e []
where
s :: Expr -> [Expr] -> [Expr]
s :: Expr -> [Expr] -> [Expr]
s e :: Expr
e@(Expr
e1 :$ Expr
e2) = (Expr
eExpr -> [Expr] -> [Expr]
forall a. a -> [a] -> [a]
:) ([Expr] -> [Expr]) -> ([Expr] -> [Expr]) -> [Expr] -> [Expr]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr -> [Expr] -> [Expr]
s Expr
e1 ([Expr] -> [Expr]) -> ([Expr] -> [Expr]) -> [Expr] -> [Expr]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr -> [Expr] -> [Expr]
s Expr
e2
s Expr
e = (Expr
eExpr -> [Expr] -> [Expr]
forall a. a -> [a] -> [a]
:)
nubSubexprs :: Expr -> [Expr]
nubSubexprs :: Expr -> [Expr]
nubSubexprs = Expr -> [Expr]
s
where
s :: Expr -> [Expr]
s e :: Expr
e@(Expr
e1 :$ Expr
e2) = [Expr
e] [Expr] -> [Expr] -> [Expr]
forall a. Ord a => [a] -> [a] -> [a]
+++ Expr -> [Expr]
s Expr
e1 [Expr] -> [Expr] -> [Expr]
forall a. Ord a => [a] -> [a] -> [a]
+++ Expr -> [Expr]
s Expr
e2
s Expr
e = [Expr
e]
values :: Expr -> [Expr]
values :: Expr -> [Expr]
values Expr
e = Expr -> [Expr] -> [Expr]
v Expr
e []
where
v :: Expr -> [Expr] -> [Expr]
v :: Expr -> [Expr] -> [Expr]
v (Expr
e1 :$ Expr
e2) = Expr -> [Expr] -> [Expr]
v Expr
e1 ([Expr] -> [Expr]) -> ([Expr] -> [Expr]) -> [Expr] -> [Expr]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr -> [Expr] -> [Expr]
v Expr
e2
v Expr
e = (Expr
eExpr -> [Expr] -> [Expr]
forall a. a -> [a] -> [a]
:)
nubValues :: Expr -> [Expr]
nubValues :: Expr -> [Expr]
nubValues = Expr -> [Expr]
v
where
v :: Expr -> [Expr]
v (Expr
e1 :$ Expr
e2) = Expr -> [Expr]
v Expr
e1 [Expr] -> [Expr] -> [Expr]
forall a. Ord a => [a] -> [a] -> [a]
+++ Expr -> [Expr]
v Expr
e2
v Expr
e = [Expr
e]
consts :: Expr -> [Expr]
consts :: Expr -> [Expr]
consts = (Expr -> Bool) -> [Expr] -> [Expr]
forall a. (a -> Bool) -> [a] -> [a]
filter Expr -> Bool
isConst ([Expr] -> [Expr]) -> (Expr -> [Expr]) -> Expr -> [Expr]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr -> [Expr]
values
nubConsts :: Expr -> [Expr]
nubConsts :: Expr -> [Expr]
nubConsts = Expr -> [Expr]
c
where
c :: Expr -> [Expr]
c (Expr
e1 :$ Expr
e2) = Expr -> [Expr]
c Expr
e1 [Expr] -> [Expr] -> [Expr]
forall a. Ord a => [a] -> [a] -> [a]
+++ Expr -> [Expr]
c Expr
e2
c Expr
e = [Expr
e | Expr -> Bool
isConst Expr
e]
vars :: Expr -> [Expr]
vars :: Expr -> [Expr]
vars = (Expr -> Bool) -> [Expr] -> [Expr]
forall a. (a -> Bool) -> [a] -> [a]
filter Expr -> Bool
isVar ([Expr] -> [Expr]) -> (Expr -> [Expr]) -> Expr -> [Expr]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr -> [Expr]
values
nubVars :: Expr -> [Expr]
nubVars :: Expr -> [Expr]
nubVars = Expr -> [Expr]
v
where
v :: Expr -> [Expr]
v (Expr
e1 :$ Expr
e2) = Expr -> [Expr]
v Expr
e1 [Expr] -> [Expr] -> [Expr]
forall a. Ord a => [a] -> [a] -> [a]
+++ Expr -> [Expr]
v Expr
e2
v Expr
e = [Expr
e | Expr -> Bool
isVar Expr
e]
arity :: Expr -> Int
arity :: Expr -> Int
arity = TypeRep -> Int
tyArity (TypeRep -> Int) -> (Expr -> TypeRep) -> Expr -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr -> TypeRep
typ
size :: Expr -> Int
size :: Expr -> Int
size = [Expr] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([Expr] -> Int) -> (Expr -> [Expr]) -> Expr -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr -> [Expr]
values
depth :: Expr -> Int
depth :: Expr -> Int
depth e :: Expr
e@(Expr
_:$Expr
_) = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ [Int] -> Int
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ((Expr -> Int) -> [Expr] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map Expr -> Int
depth ([Expr] -> [Int]) -> [Expr] -> [Int]
forall a b. (a -> b) -> a -> b
$ Expr -> [Expr]
unfoldApp Expr
e)
depth Expr
_ = Int
1
height :: Expr -> Int
height :: Expr -> Int
height (Expr
e1 :$ Expr
e2) = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Expr -> Int
height Expr
e1 Int -> Int -> Int
forall a. Ord a => a -> a -> a
`max` Expr -> Int
height Expr
e2
height Expr
_ = Int
1