{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ViewPatterns #-}

-- |
-- Module      : Jikka.Core.Language.Expr
-- Description : has data types of our core language. / core 言語のためのデータ型を持ちます。
-- Copyright   : (c) Kimiyuki Onaka, 2020
-- License     : Apache License 2.0
-- Maintainer  : kimiyuki95@gmail.com
-- Stability   : experimental
-- Portability : portable
--
-- `Jikka.Core.Language.Expr` module has the basic data types for our core language.
-- They are similar to the GHC Core language.
module Jikka.Core.Language.Expr where

import Data.String (IsString)

newtype VarName = VarName String deriving (VarName -> VarName -> Bool
(VarName -> VarName -> Bool)
-> (VarName -> VarName -> Bool) -> Eq VarName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: VarName -> VarName -> Bool
$c/= :: VarName -> VarName -> Bool
== :: VarName -> VarName -> Bool
$c== :: VarName -> VarName -> Bool
Eq, Eq VarName
Eq VarName
-> (VarName -> VarName -> Ordering)
-> (VarName -> VarName -> Bool)
-> (VarName -> VarName -> Bool)
-> (VarName -> VarName -> Bool)
-> (VarName -> VarName -> Bool)
-> (VarName -> VarName -> VarName)
-> (VarName -> VarName -> VarName)
-> Ord VarName
VarName -> VarName -> Bool
VarName -> VarName -> Ordering
VarName -> VarName -> VarName
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: VarName -> VarName -> VarName
$cmin :: VarName -> VarName -> VarName
max :: VarName -> VarName -> VarName
$cmax :: VarName -> VarName -> VarName
>= :: VarName -> VarName -> Bool
$c>= :: VarName -> VarName -> Bool
> :: VarName -> VarName -> Bool
$c> :: VarName -> VarName -> Bool
<= :: VarName -> VarName -> Bool
$c<= :: VarName -> VarName -> Bool
< :: VarName -> VarName -> Bool
$c< :: VarName -> VarName -> Bool
compare :: VarName -> VarName -> Ordering
$ccompare :: VarName -> VarName -> Ordering
$cp1Ord :: Eq VarName
Ord, Int -> VarName -> ShowS
[VarName] -> ShowS
VarName -> String
(Int -> VarName -> ShowS)
-> (VarName -> String) -> ([VarName] -> ShowS) -> Show VarName
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [VarName] -> ShowS
$cshowList :: [VarName] -> ShowS
show :: VarName -> String
$cshow :: VarName -> String
showsPrec :: Int -> VarName -> ShowS
$cshowsPrec :: Int -> VarName -> ShowS
Show, ReadPrec [VarName]
ReadPrec VarName
Int -> ReadS VarName
ReadS [VarName]
(Int -> ReadS VarName)
-> ReadS [VarName]
-> ReadPrec VarName
-> ReadPrec [VarName]
-> Read VarName
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [VarName]
$creadListPrec :: ReadPrec [VarName]
readPrec :: ReadPrec VarName
$creadPrec :: ReadPrec VarName
readList :: ReadS [VarName]
$creadList :: ReadS [VarName]
readsPrec :: Int -> ReadS VarName
$creadsPrec :: Int -> ReadS VarName
Read, String -> VarName
(String -> VarName) -> IsString VarName
forall a. (String -> a) -> IsString a
fromString :: String -> VarName
$cfromString :: String -> VarName
IsString)

unVarName :: VarName -> String
unVarName :: VarName -> String
unVarName (VarName String
name) = String
name

newtype TypeName = TypeName String deriving (TypeName -> TypeName -> Bool
(TypeName -> TypeName -> Bool)
-> (TypeName -> TypeName -> Bool) -> Eq TypeName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TypeName -> TypeName -> Bool
$c/= :: TypeName -> TypeName -> Bool
== :: TypeName -> TypeName -> Bool
$c== :: TypeName -> TypeName -> Bool
Eq, Eq TypeName
Eq TypeName
-> (TypeName -> TypeName -> Ordering)
-> (TypeName -> TypeName -> Bool)
-> (TypeName -> TypeName -> Bool)
-> (TypeName -> TypeName -> Bool)
-> (TypeName -> TypeName -> Bool)
-> (TypeName -> TypeName -> TypeName)
-> (TypeName -> TypeName -> TypeName)
-> Ord TypeName
TypeName -> TypeName -> Bool
TypeName -> TypeName -> Ordering
TypeName -> TypeName -> TypeName
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: TypeName -> TypeName -> TypeName
$cmin :: TypeName -> TypeName -> TypeName
max :: TypeName -> TypeName -> TypeName
$cmax :: TypeName -> TypeName -> TypeName
>= :: TypeName -> TypeName -> Bool
$c>= :: TypeName -> TypeName -> Bool
> :: TypeName -> TypeName -> Bool
$c> :: TypeName -> TypeName -> Bool
<= :: TypeName -> TypeName -> Bool
$c<= :: TypeName -> TypeName -> Bool
< :: TypeName -> TypeName -> Bool
$c< :: TypeName -> TypeName -> Bool
compare :: TypeName -> TypeName -> Ordering
$ccompare :: TypeName -> TypeName -> Ordering
$cp1Ord :: Eq TypeName
Ord, Int -> TypeName -> ShowS
[TypeName] -> ShowS
TypeName -> String
(Int -> TypeName -> ShowS)
-> (TypeName -> String) -> ([TypeName] -> ShowS) -> Show TypeName
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TypeName] -> ShowS
$cshowList :: [TypeName] -> ShowS
show :: TypeName -> String
$cshow :: TypeName -> String
showsPrec :: Int -> TypeName -> ShowS
$cshowsPrec :: Int -> TypeName -> ShowS
Show, ReadPrec [TypeName]
ReadPrec TypeName
Int -> ReadS TypeName
ReadS [TypeName]
(Int -> ReadS TypeName)
-> ReadS [TypeName]
-> ReadPrec TypeName
-> ReadPrec [TypeName]
-> Read TypeName
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [TypeName]
$creadListPrec :: ReadPrec [TypeName]
readPrec :: ReadPrec TypeName
$creadPrec :: ReadPrec TypeName
readList :: ReadS [TypeName]
$creadList :: ReadS [TypeName]
readsPrec :: Int -> ReadS TypeName
$creadsPrec :: Int -> ReadS TypeName
Read, String -> TypeName
(String -> TypeName) -> IsString TypeName
forall a. (String -> a) -> IsString a
fromString :: String -> TypeName
$cfromString :: String -> TypeName
IsString)

unTypeName :: TypeName -> String
unTypeName :: TypeName -> String
unTypeName (TypeName String
name) = String
name

-- | `Type` represents the types of our core language. This is similar to the `Type` of GHC Core.
-- See also [commentary/compiler/type-type](https://gitlab.haskell.org/ghc/ghc/-/wikis/commentary/compiler/type-type).
--
-- \[
--     \newcommand\int{\mathbf{int}}
--     \newcommand\bool{\mathbf{bool}}
--     \newcommand\list{\mathbf{list}}
--     \begin{array}{rl}
--         \tau ::= & \alpha \\
--         \vert & \int \\
--         \vert & \bool \\
--         \vert & \list(\tau) \\
--         \vert & \tau \times \tau \times \dots \times \tau \\
--         \vert & \tau \to \tau
--         \vert & \mathrm{data-structure}
--     \end{array}
-- \]
data Type
  = VarTy TypeName
  | IntTy
  | BoolTy
  | ListTy Type
  | TupleTy [Type]
  | FunTy Type Type
  | DataStructureTy DataStructure
  deriving (Type -> Type -> Bool
(Type -> Type -> Bool) -> (Type -> Type -> Bool) -> Eq Type
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Type -> Type -> Bool
$c/= :: Type -> Type -> Bool
== :: Type -> Type -> Bool
$c== :: Type -> Type -> Bool
Eq, Eq Type
Eq Type
-> (Type -> Type -> Ordering)
-> (Type -> Type -> Bool)
-> (Type -> Type -> Bool)
-> (Type -> Type -> Bool)
-> (Type -> Type -> Bool)
-> (Type -> Type -> Type)
-> (Type -> Type -> Type)
-> Ord Type
Type -> Type -> Bool
Type -> Type -> Ordering
Type -> Type -> Type
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Type -> Type -> Type
$cmin :: Type -> Type -> Type
max :: Type -> Type -> Type
$cmax :: Type -> Type -> Type
>= :: Type -> Type -> Bool
$c>= :: Type -> Type -> Bool
> :: Type -> Type -> Bool
$c> :: Type -> Type -> Bool
<= :: Type -> Type -> Bool
$c<= :: Type -> Type -> Bool
< :: Type -> Type -> Bool
$c< :: Type -> Type -> Bool
compare :: Type -> Type -> Ordering
$ccompare :: Type -> Type -> Ordering
$cp1Ord :: Eq Type
Ord, Int -> Type -> ShowS
[Type] -> ShowS
Type -> String
(Int -> Type -> ShowS)
-> (Type -> String) -> ([Type] -> ShowS) -> Show Type
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Type] -> ShowS
$cshowList :: [Type] -> ShowS
show :: Type -> String
$cshow :: Type -> String
showsPrec :: Int -> Type -> ShowS
$cshowsPrec :: Int -> Type -> ShowS
Show, ReadPrec [Type]
ReadPrec Type
Int -> ReadS Type
ReadS [Type]
(Int -> ReadS Type)
-> ReadS [Type] -> ReadPrec Type -> ReadPrec [Type] -> Read Type
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Type]
$creadListPrec :: ReadPrec [Type]
readPrec :: ReadPrec Type
$creadPrec :: ReadPrec Type
readList :: ReadS [Type]
$creadList :: ReadS [Type]
readsPrec :: Int -> ReadS Type
$creadsPrec :: Int -> ReadS Type
Read)

data DataStructure
  = ConvexHullTrick
  | SegmentTree Semigroup'
  deriving (DataStructure -> DataStructure -> Bool
(DataStructure -> DataStructure -> Bool)
-> (DataStructure -> DataStructure -> Bool) -> Eq DataStructure
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DataStructure -> DataStructure -> Bool
$c/= :: DataStructure -> DataStructure -> Bool
== :: DataStructure -> DataStructure -> Bool
$c== :: DataStructure -> DataStructure -> Bool
Eq, Eq DataStructure
Eq DataStructure
-> (DataStructure -> DataStructure -> Ordering)
-> (DataStructure -> DataStructure -> Bool)
-> (DataStructure -> DataStructure -> Bool)
-> (DataStructure -> DataStructure -> Bool)
-> (DataStructure -> DataStructure -> Bool)
-> (DataStructure -> DataStructure -> DataStructure)
-> (DataStructure -> DataStructure -> DataStructure)
-> Ord DataStructure
DataStructure -> DataStructure -> Bool
DataStructure -> DataStructure -> Ordering
DataStructure -> DataStructure -> DataStructure
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: DataStructure -> DataStructure -> DataStructure
$cmin :: DataStructure -> DataStructure -> DataStructure
max :: DataStructure -> DataStructure -> DataStructure
$cmax :: DataStructure -> DataStructure -> DataStructure
>= :: DataStructure -> DataStructure -> Bool
$c>= :: DataStructure -> DataStructure -> Bool
> :: DataStructure -> DataStructure -> Bool
$c> :: DataStructure -> DataStructure -> Bool
<= :: DataStructure -> DataStructure -> Bool
$c<= :: DataStructure -> DataStructure -> Bool
< :: DataStructure -> DataStructure -> Bool
$c< :: DataStructure -> DataStructure -> Bool
compare :: DataStructure -> DataStructure -> Ordering
$ccompare :: DataStructure -> DataStructure -> Ordering
$cp1Ord :: Eq DataStructure
Ord, Int -> DataStructure -> ShowS
[DataStructure] -> ShowS
DataStructure -> String
(Int -> DataStructure -> ShowS)
-> (DataStructure -> String)
-> ([DataStructure] -> ShowS)
-> Show DataStructure
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DataStructure] -> ShowS
$cshowList :: [DataStructure] -> ShowS
show :: DataStructure -> String
$cshow :: DataStructure -> String
showsPrec :: Int -> DataStructure -> ShowS
$cshowsPrec :: Int -> DataStructure -> ShowS
Show, ReadPrec [DataStructure]
ReadPrec DataStructure
Int -> ReadS DataStructure
ReadS [DataStructure]
(Int -> ReadS DataStructure)
-> ReadS [DataStructure]
-> ReadPrec DataStructure
-> ReadPrec [DataStructure]
-> Read DataStructure
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [DataStructure]
$creadListPrec :: ReadPrec [DataStructure]
readPrec :: ReadPrec DataStructure
$creadPrec :: ReadPrec DataStructure
readList :: ReadS [DataStructure]
$creadList :: ReadS [DataStructure]
readsPrec :: Int -> ReadS DataStructure
$creadsPrec :: Int -> ReadS DataStructure
Read)

data Semigroup'
  = SemigroupIntPlus
  | SemigroupIntMin
  | SemigroupIntMax
  deriving (Semigroup' -> Semigroup' -> Bool
(Semigroup' -> Semigroup' -> Bool)
-> (Semigroup' -> Semigroup' -> Bool) -> Eq Semigroup'
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Semigroup' -> Semigroup' -> Bool
$c/= :: Semigroup' -> Semigroup' -> Bool
== :: Semigroup' -> Semigroup' -> Bool
$c== :: Semigroup' -> Semigroup' -> Bool
Eq, Eq Semigroup'
Eq Semigroup'
-> (Semigroup' -> Semigroup' -> Ordering)
-> (Semigroup' -> Semigroup' -> Bool)
-> (Semigroup' -> Semigroup' -> Bool)
-> (Semigroup' -> Semigroup' -> Bool)
-> (Semigroup' -> Semigroup' -> Bool)
-> (Semigroup' -> Semigroup' -> Semigroup')
-> (Semigroup' -> Semigroup' -> Semigroup')
-> Ord Semigroup'
Semigroup' -> Semigroup' -> Bool
Semigroup' -> Semigroup' -> Ordering
Semigroup' -> Semigroup' -> Semigroup'
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Semigroup' -> Semigroup' -> Semigroup'
$cmin :: Semigroup' -> Semigroup' -> Semigroup'
max :: Semigroup' -> Semigroup' -> Semigroup'
$cmax :: Semigroup' -> Semigroup' -> Semigroup'
>= :: Semigroup' -> Semigroup' -> Bool
$c>= :: Semigroup' -> Semigroup' -> Bool
> :: Semigroup' -> Semigroup' -> Bool
$c> :: Semigroup' -> Semigroup' -> Bool
<= :: Semigroup' -> Semigroup' -> Bool
$c<= :: Semigroup' -> Semigroup' -> Bool
< :: Semigroup' -> Semigroup' -> Bool
$c< :: Semigroup' -> Semigroup' -> Bool
compare :: Semigroup' -> Semigroup' -> Ordering
$ccompare :: Semigroup' -> Semigroup' -> Ordering
$cp1Ord :: Eq Semigroup'
Ord, Int -> Semigroup' -> ShowS
[Semigroup'] -> ShowS
Semigroup' -> String
(Int -> Semigroup' -> ShowS)
-> (Semigroup' -> String)
-> ([Semigroup'] -> ShowS)
-> Show Semigroup'
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Semigroup'] -> ShowS
$cshowList :: [Semigroup'] -> ShowS
show :: Semigroup' -> String
$cshow :: Semigroup' -> String
showsPrec :: Int -> Semigroup' -> ShowS
$cshowsPrec :: Int -> Semigroup' -> ShowS
Show, ReadPrec [Semigroup']
ReadPrec Semigroup'
Int -> ReadS Semigroup'
ReadS [Semigroup']
(Int -> ReadS Semigroup')
-> ReadS [Semigroup']
-> ReadPrec Semigroup'
-> ReadPrec [Semigroup']
-> Read Semigroup'
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Semigroup']
$creadListPrec :: ReadPrec [Semigroup']
readPrec :: ReadPrec Semigroup'
$creadPrec :: ReadPrec Semigroup'
readList :: ReadS [Semigroup']
$creadList :: ReadS [Semigroup']
readsPrec :: Int -> ReadS Semigroup'
$creadsPrec :: Int -> ReadS Semigroup'
Read)

-- | TODO: What is the difference between `Literal` and `Builtin`?
data Builtin
  = -- arithmetical functions

    -- | \(: \int \to \int\)
    Negate
  | -- | \(: \int \to \int \to \int\)
    Plus
  | -- | \(: \int \to \int \to \int\)
    Minus
  | -- | \(: \int \to \int \to \int\)
    Mult
  | -- | \(: \int \to \int \to \int\)
    FloorDiv
  | -- | \(: \int \to \int \to \int\)
    FloorMod
  | -- | \(: \int \to \int \to \int\)
    CeilDiv
  | -- | \(: \int \to \int \to \int\)
    CeilMod
  | -- | \(: \int \to \int \to \int\)
    Pow
  | -- advanced arithmetical functions

    -- | \(: \int \to \int\)
    Abs
  | -- | \(: \int \to \int \to \int\)
    Gcd
  | -- | \(: \int \to \int \to \int\)
    Lcm
  | -- | \(: \forall \alpha. \alpha \to \alpha \to \alpha\)
    Min2 Type
  | -- | \(: \forall \alpha. \alpha \to \alpha \to \alpha\)
    Max2 Type
  | -- | iterated application \((\lambda k f x. f^k(x)): \forall \alpha. \int \to (\alpha \to \alpha) \to \alpha \to \alpha\)
    Iterate Type
  | -- logical functions

    -- | \(: \bool \to \bool\)
    Not
  | -- | \(: \bool \to \bool \to \bool\)
    And
  | -- | \(: \bool \to \bool \to \bool\)
    Or
  | -- | \(: \bool \to \bool \to \bool\)
    Implies
  | -- | \(: \forall \alpha. \bool \to \alpha \to \alpha \to \alpha\)
    If Type
  | -- bitwise functions

    -- | \(: \int \to \int\)
    BitNot
  | -- | \(: \int \to \int \to \int\)
    BitAnd
  | -- | \(: \int \to \int \to \int\)
    BitOr
  | -- | \(: \int \to \int \to \int\)
    BitXor
  | -- | \(: \int \to \int \to \int\)
    BitLeftShift
  | -- | \(: \int \to \int \to \int\)
    BitRightShift
  | -- matrix functions

    -- | matrix application \(: \int^{H \times W} \to \int^W \to \int^H\)
    MatAp Int Int
  | -- | zero matrix \(: \to \int^{n \times n}\)
    MatZero Int
  | -- | unit matrix \(: \to \int^{n \times n}\)
    MatOne Int
  | -- | matrix addition \(: \int^{H \times W} \to \int^{H \times W} \to \int^{H \times W}\)
    MatAdd Int Int
  | -- | matrix multiplication \(: \int^{H \times n} \to \int^{n \times W} \to \int^{H \times W}\)
    MatMul Int Int Int
  | -- | matrix power \(: \int^{n \times n} \to \int \to \int^{n \times n}\)
    MatPow Int
  | -- | vector point-wise floor-mod \(: \int^{n} \to \int \to \int^{n}\)
    VecFloorMod Int
  | -- | matrix point-wise floor-mod \(: \int^{H \times W} \to \int \to \int^{H \times W}\)
    MatFloorMod Int Int
  | -- modular functions

    -- | \(: \int \to \int \to \int\)
    ModNegate
  | -- | \(: \int \to \int \to \int \to \int\)
    ModPlus
  | -- | \(: \int \to \int \to \int \to \int\)
    ModMinus
  | -- | \(: \int \to \int \to \int \to \int\)
    ModMult
  | -- | \(: \int \to \int \to \int\)
    ModInv
  | -- | \(: \int \to \int \to \int \to \int\)
    ModPow
  | -- | matrix application \(: \int^{H \times W} \to \int^W \to \int \to \int^H\)
    ModMatAp Int Int
  | -- | matrix addition \(: \int^{H \times W} \to \int^{H \times W} \to \int \to \int^{H \times W}\)
    ModMatAdd Int Int
  | -- | matrix multiplication \(: \int^{H \times n} \to \int^{n \times W} \to \int \to \int^{H \times W}\)
    ModMatMul Int Int Int
  | -- | matrix power \(: \int^{n \times n} \to \int \to \int^{n \times n}\)
    ModMatPow Int
  | -- list functions

    -- | \(: \forall \alpha. \alpha \to \list(\alpha) \to \list(\alpha)\)
    Cons Type
  | -- | \(: \forall \alpha. \list(alpha) \to \alpha \to \list(\alpha)\)
    Snoc Type
  | -- | \(: \forall \alpha \beta. (\beta \to \alpha \to \beta) \to \beta \to \list(\alpha) \to \beta\)
    Foldl Type Type
  | -- | \(: \forall \alpha \beta. (\beta \to \alpha \to \beta) \to \beta \to \list(\alpha) \to \list(\beta)\)
    Scanl Type Type
  | -- | \(\lambda f a n.\) repeat @a <- snoc a (f a)@ @n@ times \(: \forall \alpha. (\list(\alpha) \to \alpha) \to \list(\alpha) \to \int \to \list(\alpha)\)
    Build Type
  | -- | \(: \forall \alpha. \list(\alpha) \to \int\)
    Len Type
  | -- | \(: \forall \alpha \beta. (\alpha \to \beta) \to \list(\alpha) \to \list(\beta)\)
    Map Type Type
  | -- | \(: \forall \alpha \beta. (\alpha \to \bool) \to \list(\alpha) \to \list(\beta)\)
    Filter Type
  | -- | \(: \forall \alpha. \list(\alpha) \to \int \to \alpha\)
    At Type
  | -- | \(: \forall \alpha. \list(\alpha) \to \int \to \alpha \to \list(\alpha)\)
    SetAt Type
  | -- | \(: \forall \alpha. \alpha \to \list(\alpha) \to \bool\)
    Elem Type
  | -- | \(: \list(\int) \to \int\)
    Sum
  | -- | \(: \list(\int) \to \int\)
    Product
  | -- | \(: \list(\int) \to \int \to \int\)
    ModSum
  | -- | \(: \list(\int) \to \int \to \int\)
    ModProduct
  | -- | \(: \forall \alpha. \list(\alpha) \to \alpha\)
    Min1 Type
  | -- | \(: \forall \alpha. \list(\alpha) \to \alpha\)
    Max1 Type
  | -- | \(: \forall \alpha. \list(\alpha) \to \int\)
    ArgMin Type
  | -- | \(: \forall \alpha. \list(\alpha) \to \int\)
    ArgMax Type
  | -- | \(: \list(\bool) \to \bool\)
    All
  | -- | \(: \list(\bool) \to \bool\)
    Any
  | -- | \(: \forall \alpha. \list(\alpha) \to \list(\alpha)\)
    Sorted Type
  | -- | \(: \forall \alpha. \list(\alpha) \to \list(\alpha)\)
    Reversed Type
  | -- | \(: \int \to \list(\int)\)
    Range1
  | -- | \(: \int \to \int \to \list(\int)\)
    Range2
  | -- | \(: \int \to \int \to \int \to \list(\int)\)
    Range3
  | -- tuple functions

    -- | \(: \forall \alpha_0 \alpha_1 \dots \alpha _ {n - 1}. \alpha_0 \to \dots \to \alpha _ {n - 1} \to \alpha_0 \times \dots \times \alpha _ {n - 1}\)
    Tuple [Type]
  | -- | \(: \forall \alpha_0 \alpha_1 \dots \alpha _ {n - 1}. \alpha_0 \times \dots \times \alpha _ {n - 1} \to \alpha_i\)
    Proj [Type] Int
  | -- comparison

    -- | \(: \forall \alpha. \alpha \to \alpha \to \bool\)
    LessThan Type
  | -- | \(: \forall \alpha. \alpha \to \alpha \to \bool\)
    LessEqual Type
  | -- | \(: \forall \alpha. \alpha \to \alpha \to \bool\)
    GreaterThan Type
  | -- | \(: \forall \alpha. \alpha \to \alpha \to \bool\)
    GreaterEqual Type
  | -- | \(: \forall \alpha. \alpha \to \alpha \to \bool\)
    Equal Type
  | -- | \(: \forall \alpha. \alpha \to \alpha \to \bool\)
    NotEqual Type
  | -- combinational functions

    -- | \(: \int \to \int\)
    Fact
  | -- | \(: \int \to \int \to \int\)
    Choose
  | -- | \(: \int \to \int \to \int\)
    Permute
  | -- | \(: \int \to \int \to \int\)
    MultiChoose
  | -- data structures

    -- | \(: \mathrm{convex-hull-trick}\)
    ConvexHullTrickInit
  | -- | \(: \mathrm{convex-hull-trick} \to \int \to \int\)
    ConvexHullTrickGetMin
  | -- | \(: \mathrm{convex-hull-trick} \to \int \to \int \to \mathrm{convex-hull-trick}\)
    ConvexHullTrickInsert
  | -- | \(: \forall S. \list(S) \to \mathrm{segment-tree}(S)\)
    SegmentTreeInitList Semigroup'
  | -- | \(: \forall S. \mathrm{segment-tree}(S) \to \int \to \int \to S\)
    SegmentTreeGetRange Semigroup'
  | -- | \(: \forall S. \mathrm{segment-tree}(S) \to \int \to S \to \mathrm{segment-tree}(S)\)
    SegmentTreeSetPoint Semigroup'
  deriving (Builtin -> Builtin -> Bool
(Builtin -> Builtin -> Bool)
-> (Builtin -> Builtin -> Bool) -> Eq Builtin
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Builtin -> Builtin -> Bool
$c/= :: Builtin -> Builtin -> Bool
== :: Builtin -> Builtin -> Bool
$c== :: Builtin -> Builtin -> Bool
Eq, Eq Builtin
Eq Builtin
-> (Builtin -> Builtin -> Ordering)
-> (Builtin -> Builtin -> Bool)
-> (Builtin -> Builtin -> Bool)
-> (Builtin -> Builtin -> Bool)
-> (Builtin -> Builtin -> Bool)
-> (Builtin -> Builtin -> Builtin)
-> (Builtin -> Builtin -> Builtin)
-> Ord Builtin
Builtin -> Builtin -> Bool
Builtin -> Builtin -> Ordering
Builtin -> Builtin -> Builtin
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Builtin -> Builtin -> Builtin
$cmin :: Builtin -> Builtin -> Builtin
max :: Builtin -> Builtin -> Builtin
$cmax :: Builtin -> Builtin -> Builtin
>= :: Builtin -> Builtin -> Bool
$c>= :: Builtin -> Builtin -> Bool
> :: Builtin -> Builtin -> Bool
$c> :: Builtin -> Builtin -> Bool
<= :: Builtin -> Builtin -> Bool
$c<= :: Builtin -> Builtin -> Bool
< :: Builtin -> Builtin -> Bool
$c< :: Builtin -> Builtin -> Bool
compare :: Builtin -> Builtin -> Ordering
$ccompare :: Builtin -> Builtin -> Ordering
$cp1Ord :: Eq Builtin
Ord, Int -> Builtin -> ShowS
[Builtin] -> ShowS
Builtin -> String
(Int -> Builtin -> ShowS)
-> (Builtin -> String) -> ([Builtin] -> ShowS) -> Show Builtin
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Builtin] -> ShowS
$cshowList :: [Builtin] -> ShowS
show :: Builtin -> String
$cshow :: Builtin -> String
showsPrec :: Int -> Builtin -> ShowS
$cshowsPrec :: Int -> Builtin -> ShowS
Show, ReadPrec [Builtin]
ReadPrec Builtin
Int -> ReadS Builtin
ReadS [Builtin]
(Int -> ReadS Builtin)
-> ReadS [Builtin]
-> ReadPrec Builtin
-> ReadPrec [Builtin]
-> Read Builtin
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Builtin]
$creadListPrec :: ReadPrec [Builtin]
readPrec :: ReadPrec Builtin
$creadPrec :: ReadPrec Builtin
readList :: ReadS [Builtin]
$creadList :: ReadS [Builtin]
readsPrec :: Int -> ReadS Builtin
$creadsPrec :: Int -> ReadS Builtin
Read)

data Literal
  = LitBuiltin Builtin
  | -- | \(: \forall \alpha. \int\)
    LitInt Integer
  | -- | \(: \forall \alpha. \bool\)
    LitBool Bool
  | -- | \(: \forall \alpha. \list(\alpha)\)
    LitNil Type
  | -- | \(: \bot : \forall \alpha. \alpha\). The second argument is its error message.
    LitBottom Type String
  deriving (Literal -> Literal -> Bool
(Literal -> Literal -> Bool)
-> (Literal -> Literal -> Bool) -> Eq Literal
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Literal -> Literal -> Bool
$c/= :: Literal -> Literal -> Bool
== :: Literal -> Literal -> Bool
$c== :: Literal -> Literal -> Bool
Eq, Eq Literal
Eq Literal
-> (Literal -> Literal -> Ordering)
-> (Literal -> Literal -> Bool)
-> (Literal -> Literal -> Bool)
-> (Literal -> Literal -> Bool)
-> (Literal -> Literal -> Bool)
-> (Literal -> Literal -> Literal)
-> (Literal -> Literal -> Literal)
-> Ord Literal
Literal -> Literal -> Bool
Literal -> Literal -> Ordering
Literal -> Literal -> Literal
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Literal -> Literal -> Literal
$cmin :: Literal -> Literal -> Literal
max :: Literal -> Literal -> Literal
$cmax :: Literal -> Literal -> Literal
>= :: Literal -> Literal -> Bool
$c>= :: Literal -> Literal -> Bool
> :: Literal -> Literal -> Bool
$c> :: Literal -> Literal -> Bool
<= :: Literal -> Literal -> Bool
$c<= :: Literal -> Literal -> Bool
< :: Literal -> Literal -> Bool
$c< :: Literal -> Literal -> Bool
compare :: Literal -> Literal -> Ordering
$ccompare :: Literal -> Literal -> Ordering
$cp1Ord :: Eq Literal
Ord, Int -> Literal -> ShowS
[Literal] -> ShowS
Literal -> String
(Int -> Literal -> ShowS)
-> (Literal -> String) -> ([Literal] -> ShowS) -> Show Literal
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Literal] -> ShowS
$cshowList :: [Literal] -> ShowS
show :: Literal -> String
$cshow :: Literal -> String
showsPrec :: Int -> Literal -> ShowS
$cshowsPrec :: Int -> Literal -> ShowS
Show, ReadPrec [Literal]
ReadPrec Literal
Int -> ReadS Literal
ReadS [Literal]
(Int -> ReadS Literal)
-> ReadS [Literal]
-> ReadPrec Literal
-> ReadPrec [Literal]
-> Read Literal
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Literal]
$creadListPrec :: ReadPrec [Literal]
readPrec :: ReadPrec Literal
$creadPrec :: ReadPrec Literal
readList :: ReadS [Literal]
$creadList :: ReadS [Literal]
readsPrec :: Int -> ReadS Literal
$creadsPrec :: Int -> ReadS Literal
Read)

-- | `Expr` represents the exprs of our core language. This is similar to the `Expr` of GHC Core.
-- See also [commentary/compiler/core-syn-type](https://gitlab.haskell.org/ghc/ghc/-/wikis/commentary/compiler/core-syn-type).
--
-- \[
--     \begin{array}{rl}
--         e ::= & x \\
--         \vert & \mathrm{literal}\ldots \\
--         \vert & e_0(e_1, e_2, \dots, e_n) \\
--         \vert & \lambda ~ x_0\colon \tau_0, x_1\colon \tau_1, \dots, x_{n-1}\colon \tau_{n-1}. ~ e \\
--         \vert & \mathbf{let} ~ x\colon \tau = e_1 ~ \mathbf{in} ~ e_2
--     \end{array}
-- \]
data Expr
  = Var VarName
  | Lit Literal
  | -- | The functions are not curried.
    App Expr Expr
  | -- | The lambdas are also not curried.
    Lam VarName Type Expr
  | -- | This "let" is not recursive.
    Let VarName Type Expr Expr
  deriving (Expr -> Expr -> Bool
(Expr -> Expr -> Bool) -> (Expr -> Expr -> Bool) -> Eq Expr
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Expr -> Expr -> Bool
$c/= :: Expr -> Expr -> Bool
== :: Expr -> Expr -> Bool
$c== :: Expr -> Expr -> Bool
Eq, Eq Expr
Eq Expr
-> (Expr -> Expr -> Ordering)
-> (Expr -> Expr -> Bool)
-> (Expr -> Expr -> Bool)
-> (Expr -> Expr -> Bool)
-> (Expr -> Expr -> Bool)
-> (Expr -> Expr -> Expr)
-> (Expr -> Expr -> Expr)
-> Ord Expr
Expr -> Expr -> Bool
Expr -> Expr -> Ordering
Expr -> Expr -> Expr
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Expr -> Expr -> Expr
$cmin :: Expr -> Expr -> Expr
max :: Expr -> Expr -> Expr
$cmax :: Expr -> Expr -> Expr
>= :: Expr -> Expr -> Bool
$c>= :: Expr -> Expr -> Bool
> :: Expr -> Expr -> Bool
$c> :: Expr -> Expr -> Bool
<= :: Expr -> Expr -> Bool
$c<= :: Expr -> Expr -> Bool
< :: Expr -> Expr -> Bool
$c< :: Expr -> Expr -> Bool
compare :: Expr -> Expr -> Ordering
$ccompare :: Expr -> Expr -> Ordering
$cp1Ord :: Eq Expr
Ord, Int -> Expr -> ShowS
[Expr] -> ShowS
Expr -> String
(Int -> Expr -> ShowS)
-> (Expr -> String) -> ([Expr] -> ShowS) -> Show Expr
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Expr] -> ShowS
$cshowList :: [Expr] -> ShowS
show :: Expr -> String
$cshow :: Expr -> String
showsPrec :: Int -> Expr -> ShowS
$cshowsPrec :: Int -> Expr -> ShowS
Show, ReadPrec [Expr]
ReadPrec Expr
Int -> ReadS Expr
ReadS [Expr]
(Int -> ReadS Expr)
-> ReadS [Expr] -> ReadPrec Expr -> ReadPrec [Expr] -> Read Expr
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Expr]
$creadListPrec :: ReadPrec [Expr]
readPrec :: ReadPrec Expr
$creadPrec :: ReadPrec Expr
readList :: ReadS [Expr]
$creadList :: ReadS [Expr]
readsPrec :: Int -> ReadS Expr
$creadsPrec :: Int -> ReadS Expr
Read)

pattern $bFun2Ty :: Type -> Type -> Type -> Type
$mFun2Ty :: forall r. Type -> (Type -> Type -> Type -> r) -> (Void# -> r) -> r
Fun2Ty t1 t2 ret = FunTy t1 (FunTy t2 ret)

pattern $bFun3Ty :: Type -> Type -> Type -> Type -> Type
$mFun3Ty :: forall r.
Type -> (Type -> Type -> Type -> Type -> r) -> (Void# -> r) -> r
Fun3Ty t1 t2 t3 ret = FunTy t1 (FunTy t2 (FunTy t3 ret))

pattern $bFun1STy :: Type -> Type
$mFun1STy :: forall r. Type -> (Type -> r) -> (Void# -> r) -> r
Fun1STy t <-
  (\case FunTy t1 ret | t1 == ret -> Just ret; _ -> Nothing -> Just t)
  where
    Fun1STy Type
t = Type -> Type -> Type
FunTy Type
t Type
t

pattern $bFun2STy :: Type -> Type
$mFun2STy :: forall r. Type -> (Type -> r) -> (Void# -> r) -> r
Fun2STy t <-
  (\case Fun2Ty t1 t2 ret | t1 == ret && t2 == ret -> Just ret; _ -> Nothing -> Just t)
  where
    Fun2STy Type
t = Type -> Type -> Type -> Type
Fun2Ty Type
t Type
t Type
t

pattern $bFun3STy :: Type -> Type
$mFun3STy :: forall r. Type -> (Type -> r) -> (Void# -> r) -> r
Fun3STy t <-
  (\case Fun3Ty t1 t2 t3 ret | t1 == ret && t2 == ret && t3 == ret -> Just ret; _ -> Nothing -> Just t)
  where
    Fun3STy Type
t = Type -> Type -> Type -> Type -> Type
Fun3Ty Type
t Type
t Type
t Type
t

pattern $bFunLTy :: Type -> Type
$mFunLTy :: forall r. Type -> (Type -> r) -> (Void# -> r) -> r
FunLTy t <-
  (\case FunTy (ListTy t1) ret | t1 == ret -> Just ret; _ -> Nothing -> Just t)
  where
    FunLTy Type
t = Type -> Type -> Type
FunTy (Type -> Type
ListTy Type
t) Type
t

vectorTy :: Int -> Type
vectorTy :: Int -> Type
vectorTy Int
n = [Type] -> Type
TupleTy (Int -> Type -> [Type]
forall a. Int -> a -> [a]
replicate Int
n Type
IntTy)

matrixTy :: Int -> Int -> Type
matrixTy :: Int -> Int -> Type
matrixTy Int
h Int
w = [Type] -> Type
TupleTy (Int -> Type -> [Type]
forall a. Int -> a -> [a]
replicate Int
h ([Type] -> Type
TupleTy (Int -> Type -> [Type]
forall a. Int -> a -> [a]
replicate Int
w Type
IntTy)))

pattern $bUnitTy :: Type
$mUnitTy :: forall r. Type -> (Void# -> r) -> (Void# -> r) -> r
UnitTy = TupleTy []

pattern $bConvexHullTrickTy :: Type
$mConvexHullTrickTy :: forall r. Type -> (Void# -> r) -> (Void# -> r) -> r
ConvexHullTrickTy = DataStructureTy ConvexHullTrick

pattern $bSegmentTreeTy :: Semigroup' -> Type
$mSegmentTreeTy :: forall r. Type -> (Semigroup' -> r) -> (Void# -> r) -> r
SegmentTreeTy semigrp = DataStructureTy (SegmentTree semigrp)

pattern $bLitInt' :: Integer -> Expr
$mLitInt' :: forall r. Expr -> (Integer -> r) -> (Void# -> r) -> r
LitInt' n = Lit (LitInt n)

pattern $bLit0 :: Expr
$mLit0 :: forall r. Expr -> (Void# -> r) -> (Void# -> r) -> r
Lit0 = Lit (LitInt 0)

pattern $bLit1 :: Expr
$mLit1 :: forall r. Expr -> (Void# -> r) -> (Void# -> r) -> r
Lit1 = Lit (LitInt 1)

pattern $bLit2 :: Expr
$mLit2 :: forall r. Expr -> (Void# -> r) -> (Void# -> r) -> r
Lit2 = Lit (LitInt 2)

pattern $bLitMinus1 :: Expr
$mLitMinus1 :: forall r. Expr -> (Void# -> r) -> (Void# -> r) -> r
LitMinus1 = Lit (LitInt (-1))

pattern $bLitBool' :: Bool -> Expr
$mLitBool' :: forall r. Expr -> (Bool -> r) -> (Void# -> r) -> r
LitBool' p = Lit (LitBool p)

pattern $bLitTrue :: Expr
$mLitTrue :: forall r. Expr -> (Void# -> r) -> (Void# -> r) -> r
LitTrue = Lit (LitBool True)

pattern $bLitFalse :: Expr
$mLitFalse :: forall r. Expr -> (Void# -> r) -> (Void# -> r) -> r
LitFalse = Lit (LitBool False)

pattern $bBuiltin :: Builtin -> Expr
$mBuiltin :: forall r. Expr -> (Builtin -> r) -> (Void# -> r) -> r
Builtin builtin = Lit (LitBuiltin builtin)

pattern $bApp2 :: Expr -> Expr -> Expr -> Expr
$mApp2 :: forall r. Expr -> (Expr -> Expr -> Expr -> r) -> (Void# -> r) -> r
App2 f e1 e2 = App (App f e1) e2

pattern $bApp3 :: Expr -> Expr -> Expr -> Expr -> Expr
$mApp3 :: forall r.
Expr -> (Expr -> Expr -> Expr -> Expr -> r) -> (Void# -> r) -> r
App3 f e1 e2 e3 = App (App (App f e1) e2) e3

pattern $bApp4 :: Expr -> Expr -> Expr -> Expr -> Expr -> Expr
$mApp4 :: forall r.
Expr
-> (Expr -> Expr -> Expr -> Expr -> Expr -> r) -> (Void# -> r) -> r
App4 f e1 e2 e3 e4 = App (App (App (App f e1) e2) e3) e4

pattern $bAppBuiltin :: Builtin -> Expr -> Expr
$mAppBuiltin :: forall r. Expr -> (Builtin -> Expr -> r) -> (Void# -> r) -> r
AppBuiltin builtin e1 = App (Lit (LitBuiltin builtin)) e1

pattern $bAppBuiltin2 :: Builtin -> Expr -> Expr -> Expr
$mAppBuiltin2 :: forall r.
Expr -> (Builtin -> Expr -> Expr -> r) -> (Void# -> r) -> r
AppBuiltin2 builtin e1 e2 = App2 (Lit (LitBuiltin builtin)) e1 e2

pattern $bAppBuiltin3 :: Builtin -> Expr -> Expr -> Expr -> Expr
$mAppBuiltin3 :: forall r.
Expr -> (Builtin -> Expr -> Expr -> Expr -> r) -> (Void# -> r) -> r
AppBuiltin3 builtin e1 e2 e3 = App3 (Lit (LitBuiltin builtin)) e1 e2 e3

pattern $bLam2 :: VarName -> Type -> VarName -> Type -> Expr -> Expr
$mLam2 :: forall r.
Expr
-> (VarName -> Type -> VarName -> Type -> Expr -> r)
-> (Void# -> r)
-> r
Lam2 x1 t1 x2 t2 e = Lam x1 t1 (Lam x2 t2 e)

pattern $bLam3 :: VarName
-> Type -> VarName -> Type -> VarName -> Type -> Expr -> Expr
$mLam3 :: forall r.
Expr
-> (VarName
    -> Type -> VarName -> Type -> VarName -> Type -> Expr -> r)
-> (Void# -> r)
-> r
Lam3 x1 t1 x2 t2 x3 t3 e = Lam x1 t1 (Lam x2 t2 (Lam x3 t3 e))

pattern $bLamId :: VarName -> Type -> Expr
$mLamId :: forall r. Expr -> (VarName -> Type -> r) -> (Void# -> r) -> r
LamId x t <-
  (\case Lam x t (Var y) | x == y -> Just (x, t); _ -> Nothing -> Just (x, t))
  where
    LamId VarName
x Type
t = VarName -> Type -> Expr -> Expr
Lam VarName
x Type
t (VarName -> Expr
Var VarName
x)

-- | `ToplevelExpr` is the toplevel exprs. In our core, "let rec" is allowed only on the toplevel.
--
-- \[
--     \begin{array}{rl}
--         \mathrm{tle} ::= & e \\
--         \vert & \mathbf{let}~ x: \tau = e ~\mathbf{in}~ \mathrm{tle} \\
--         \vert & \mathbf{let~rec}~ x(x: \tau, x: \tau, \dots, x: \tau): \tau = e ~\mathbf{in}~ \mathrm{tle}
--     \end{array}
-- \]
data ToplevelExpr
  = ResultExpr Expr
  | ToplevelLet VarName Type Expr ToplevelExpr
  | ToplevelLetRec VarName [(VarName, Type)] Type Expr ToplevelExpr
  deriving (ToplevelExpr -> ToplevelExpr -> Bool
(ToplevelExpr -> ToplevelExpr -> Bool)
-> (ToplevelExpr -> ToplevelExpr -> Bool) -> Eq ToplevelExpr
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ToplevelExpr -> ToplevelExpr -> Bool
$c/= :: ToplevelExpr -> ToplevelExpr -> Bool
== :: ToplevelExpr -> ToplevelExpr -> Bool
$c== :: ToplevelExpr -> ToplevelExpr -> Bool
Eq, Eq ToplevelExpr
Eq ToplevelExpr
-> (ToplevelExpr -> ToplevelExpr -> Ordering)
-> (ToplevelExpr -> ToplevelExpr -> Bool)
-> (ToplevelExpr -> ToplevelExpr -> Bool)
-> (ToplevelExpr -> ToplevelExpr -> Bool)
-> (ToplevelExpr -> ToplevelExpr -> Bool)
-> (ToplevelExpr -> ToplevelExpr -> ToplevelExpr)
-> (ToplevelExpr -> ToplevelExpr -> ToplevelExpr)
-> Ord ToplevelExpr
ToplevelExpr -> ToplevelExpr -> Bool
ToplevelExpr -> ToplevelExpr -> Ordering
ToplevelExpr -> ToplevelExpr -> ToplevelExpr
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ToplevelExpr -> ToplevelExpr -> ToplevelExpr
$cmin :: ToplevelExpr -> ToplevelExpr -> ToplevelExpr
max :: ToplevelExpr -> ToplevelExpr -> ToplevelExpr
$cmax :: ToplevelExpr -> ToplevelExpr -> ToplevelExpr
>= :: ToplevelExpr -> ToplevelExpr -> Bool
$c>= :: ToplevelExpr -> ToplevelExpr -> Bool
> :: ToplevelExpr -> ToplevelExpr -> Bool
$c> :: ToplevelExpr -> ToplevelExpr -> Bool
<= :: ToplevelExpr -> ToplevelExpr -> Bool
$c<= :: ToplevelExpr -> ToplevelExpr -> Bool
< :: ToplevelExpr -> ToplevelExpr -> Bool
$c< :: ToplevelExpr -> ToplevelExpr -> Bool
compare :: ToplevelExpr -> ToplevelExpr -> Ordering
$ccompare :: ToplevelExpr -> ToplevelExpr -> Ordering
$cp1Ord :: Eq ToplevelExpr
Ord, Int -> ToplevelExpr -> ShowS
[ToplevelExpr] -> ShowS
ToplevelExpr -> String
(Int -> ToplevelExpr -> ShowS)
-> (ToplevelExpr -> String)
-> ([ToplevelExpr] -> ShowS)
-> Show ToplevelExpr
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ToplevelExpr] -> ShowS
$cshowList :: [ToplevelExpr] -> ShowS
show :: ToplevelExpr -> String
$cshow :: ToplevelExpr -> String
showsPrec :: Int -> ToplevelExpr -> ShowS
$cshowsPrec :: Int -> ToplevelExpr -> ShowS
Show, ReadPrec [ToplevelExpr]
ReadPrec ToplevelExpr
Int -> ReadS ToplevelExpr
ReadS [ToplevelExpr]
(Int -> ReadS ToplevelExpr)
-> ReadS [ToplevelExpr]
-> ReadPrec ToplevelExpr
-> ReadPrec [ToplevelExpr]
-> Read ToplevelExpr
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [ToplevelExpr]
$creadListPrec :: ReadPrec [ToplevelExpr]
readPrec :: ReadPrec ToplevelExpr
$creadPrec :: ReadPrec ToplevelExpr
readList :: ReadS [ToplevelExpr]
$creadList :: ReadS [ToplevelExpr]
readsPrec :: Int -> ReadS ToplevelExpr
$creadsPrec :: Int -> ReadS ToplevelExpr
Read)

type Program = ToplevelExpr