plutus-core-1.60.0.0: Language library for Plutus Core
Safe HaskellSafe-Inferred
LanguageHaskell2010

Universe

Synopsis

Documentation

data Esc a #

"Escapes" a type of an arbitrary kind to fit into Type.

data Some (tag :: k -> Type) where #

Existential. This is type is useful to hide GADTs' parameters.

>>> data Tag :: Type -> Type where TagInt :: Tag Int; TagBool :: Tag Bool
>>> instance GShow Tag where gshowsPrec _ TagInt = showString "TagInt"; gshowsPrec _ TagBool = showString "TagBool"
>>> classify s = case s of "TagInt" -> [mkGReadResult TagInt]; "TagBool" -> [mkGReadResult TagBool]; _ -> []
>>> instance GRead Tag where greadsPrec _ s = [ (r, rest) | (con, rest) <-  lex s, r <- classify con ]

You can either use PatternSynonyms (available with GHC >= 8.0)

>>> let x = Some TagInt
>>> x
Some TagInt
>>> case x of { Some TagInt -> "I"; Some TagBool -> "B" } :: String
"I"

or you can use functions

>>> let y = mkSome TagBool
>>> y
Some TagBool
>>> withSome y $ \y' -> case y' of { TagInt -> "I"; TagBool -> "B" } :: String
"B"

The implementation of mapSome is safe.

>>> let f :: Tag a -> Tag a; f TagInt = TagInt; f TagBool = TagBool
>>> mapSome f y
Some TagBool

but you can also use:

>>> withSome y (mkSome . f)
Some TagBool
>>> read "Some TagBool" :: Some Tag
Some TagBool
>>> read "mkSome TagInt" :: Some Tag
Some TagInt

Bundled Patterns

pattern Some :: forall {k} tag (a :: k). () => tag a -> Some tag 

Instances

Instances details
(Closed uni, Everywhere uni PrettyConst) => PrettyBy ConstConfig (Some (ValueOf uni)) # 
Instance details

Defined in PlutusCore.Pretty.PrettyConst

Methods

prettyBy :: ConstConfig -> Some (ValueOf uni) -> Doc ann #

prettyListBy :: ConstConfig -> [Some (ValueOf uni)] -> Doc ann #

NumBits #

(Closed uni, Everywhere uni PrettyConst) => Pretty (ValueOf uni a) # 
Instance details

Defined in PlutusCore.Pretty.PrettyConst

Methods

pretty :: ValueOf uni a -> Doc ann #

prettyList :: [ValueOf uni a] -> Doc ann #

(Closed uni, Everywhere uni PrettyConst) => Pretty (Some (ValueOf uni)) # 
Instance details

Defined in PlutusCore.Pretty.PrettyConst

Methods

pretty :: Some (ValueOf uni) -> Doc ann #

prettyList :: [Some (ValueOf uni)] -> Doc ann #

class Contains uni a where #

A class for enumerating types and fully instantiated type formers that uni contains. For example, a particular ExampleUni may have monomorphic types in it:

instance ExampleUni Contains Integer where ... instance ExampleUni Contains Bool where ...

as well as polymorphic ones:

instance ExampleUni Contains [] where ... instance ExampleUni Contains (,) where ...

as well as their instantiations:

instance ExampleUni Contains a => ExampleUni Contains [a] where ... instance (ExampleUni Contains a, ExampleUni Contains b) => ExampleUni Contains (a, b) where ...

(a universe can have any subset of the mentioned sorts of types, for example it's fine to have instantiated polymorphic types and not have uninstantiated ones and vice versa)

Note that when used as a constraint of a function Contains does not allow you to directly express things like "uni has the Integer, Bool and [] types and type formers", because [] is not fully instantiated. So you can only say "uni has Integer, Bool, [Integer], [Bool], [[Integer]], [[Bool]] etc" and such manual enumeration is annoying, so we'd really like to be able to say that uni has lists of arbitrary built-in types (including lists of lists etc). Contains does not allow that, but Includes does. For example, in the body of the following definition:

foo :: (uni Includes Integer, uni Includes Bool, uni Includes []) => ... foo = ...

you can make use of the fact that uni has lists of arbitrary included types (integers, booleans and lists).

Hence most of the time opt for using the more flexible Includes.

Includes is defined in terms of Contains, so you only need to provide a Contains instance per type from the universe and you'll get Includes for free.

Methods

knownUni :: uni (Esc a) #

Instances

Instances details
Contains DefaultUni Text) #

Contains DefaultUni Vector) #

Contains DefaultUni List # 
Instance details

Defined in PlutusCore.Default.Universe

(TypeError NoStandalonePolymorphicDataErrMsg :: Constraint) => Contains uni (TyVarRep :: TyNameRep kind -> kind) # 
Instance details

Defined in PlutusCore.Builtin.Polymorphism

Methods

knownUni :: uni (Esc TyVarRep) #

type Includes uni = Permits (Contains uni) #

uni Includes a reads as "a is in the uni". a can be of a higher-kind, see the docs of Contains on why you might want that.

knownUniOf :: uni `Contains` a => proxy a -> uni (Esc a) #

Same as knownUni, but receives a proxy.

someType :: forall k (a :: k) uni. uni `Contains` a => SomeTypeIn uni #

Wrap a type into SomeTypeIn, provided it's in the universe.

someValueOf :: forall a uni. uni (Esc a) -> a -> Some (ValueOf uni) #

Wrap a value into Some (ValueOf uni), given its explicit type tag.

someValue :: forall a uni. uni `Contains` a => a -> Some (ValueOf uni) #

Wrap a value into Some (ValueOf uni), provided its type is in the universe.

newtype DecodeUniM a #

A monad to decode types from a universe in. We use a monad for decoding, because parsing arguments of polymorphic built-in types can peel off an arbitrary amount of type tags from the input list of tags and so we have state, which is convenient to handle with, well, StateT.

Constructors

DecodeUniM 

Fields

Instances

Instances details
MonadFail DecodeUniM # 
Instance details

Defined in Universe.Core

Methods

fail :: String -> DecodeUniM a #

Alternative DecodeUniM # 
Instance details

Defined in Universe.Core

Applicative DecodeUniM # 
Instance details

Defined in Universe.Core

Methods

pure :: a -> DecodeUniM a #

(<*>) :: DecodeUniM (a -> b) -> DecodeUniM a -> DecodeUniM b #

liftA2 :: (a -> b -> c) -> DecodeUniM a -> DecodeUniM b -> DecodeUniM c #

(*>) :: DecodeUniM a -> DecodeUniM b -> DecodeUniM b #

(<*) :: DecodeUniM a -> DecodeUniM b -> DecodeUniM a #

Functor DecodeUniM # 
Instance details

Defined in Universe.Core

Methods

fmap :: (a -> b) -> DecodeUniM a -> DecodeUniM b #

(<$) :: a -> DecodeUniM b -> DecodeUniM a #

Monad DecodeUniM # 
Instance details

Defined in Universe.Core

Methods

(>>=) :: DecodeUniM a -> (a -> DecodeUniM b) -> DecodeUniM b #

(>>) :: DecodeUniM a -> DecodeUniM b -> DecodeUniM b #

return :: a -> DecodeUniM a #

MonadPlus DecodeUniM # 
Instance details

Defined in Universe.Core

class Closed uni where #

A universe is Closed, if it's known how to constrain every type from the universe and every type can be encoded to / decoded from a sequence of integer tags. The universe doesn't have to be finite and providing support for infinite universes is the reason why we encode a type as a sequence of integer tags as opposed to a single integer tag. For example, given

  data U a where
      UList :: !(U a) -> U [a]
      UInt  :: U Int

UList (UList UInt) can be encoded to [0,0,1] where 0 and 1 are the integer tags of the UList and UInt constructors, respectively.

Associated Types

type Everywhere uni (constr :: Type -> Constraint) :: Constraint #

A constrant for "constr a holds for any a from uni".

Methods

encodeUni :: uni a -> [Int] #

Encode a type as a sequence of Int tags. The opposite of decodeUni.

withDecodedUni :: (forall k (a :: k). Typeable k => uni (Esc a) -> DecodeUniM r) -> DecodeUniM r #

Decode a type and feed it to the continuation.

bring :: uni `Everywhere` constr => proxy constr -> uni (Esc a) -> (constr a => r) -> r #

Bring a constr a instance in scope, provided a is a type from the universe and constr holds for any type from the universe.

Instances

Instances details
Closed DefaultUni # 
Instance details

Defined in PlutusCore.Default.Universe

Associated Types

type Everywhere DefaultUni constr #

Methods

encodeUni :: DefaultUni a -> [Int] #

withDecodedUni :: (forall k (a :: k). Typeable k => DefaultUni (Esc a) -> DecodeUniM r) -> DecodeUniM r #

bring :: Everywhere DefaultUni constr => proxy constr -> DefaultUni (Esc a) -> (constr a => r) -> r #

decodeKindedUni :: Closed uni => [Int] -> Maybe (SomeTypeIn (Kinded uni)) #

Decode a type from a sequence of Int tags. The opposite of encodeUni (modulo invalid input).

peelUniTag :: DecodeUniM Int #

Peel off a tag from the input list of type tags.

type family Permits constr #

constr Permits f elaborates to one of - constr f forall a. constr a => constr (f a) forall a b. (constr a, constr b) => constr (f a b) forall a b c. (constr a, constr b, constr c) => constr (f a b c)

depending on the kind of f. This allows us to say things like

( constr Permits Integer , constr Permits [] , constr Permits (,) )

and thus constraint every type from the universe (including polymorphic ones) to satisfy constr, which is how we provide an implementation of Everywhere for universes with polymorphic types.

Permits is an open type family, so you can provide type instances for fs expecting more type arguments than 3 if you need that.

Note that, say, constr Permits [] elaborates to

forall a. constr a => constr [a]

and for certain type classes that does not make sense (e.g. the Generic instance of [] does not require the type of elements to be Generic), however it's not a problem because we use Permit to constrain the whole universe and so we know that arguments of polymorphic built-in types are builtins themselves are hence do satisfy the constraint and the fact that these constraints on arguments do not get used in the polymorphic case only means that they get ignored.

Instances

Instances details
type Permits constr # 
Instance details

Defined in Universe.Core

type Permits constr
type Permits constr # 
Instance details

Defined in Universe.Core

type Permits constr
type Permits constr # 
Instance details

Defined in Universe.Core

type Permits constr
type Permits constr # 
Instance details

Defined in Universe.Core

type Permits constr

type family EverywhereAll uni constrs where ... #

Equations

EverywhereAll uni '[] = () 
EverywhereAll uni (constr ': constrs) = (uni `Everywhere` constr, uni `EverywhereAll` constrs) 

type (<:) uni1 uni2 = uni1 `Everywhere` Includes uni2 #

A constraint for "uni1 is a subuniverse of uni2".

class HasUniApply (uni :: Type -> Type) where #

A class for "uni has general type application".

Methods

uniApply :: forall k l (f :: k -> l) a. uni (Esc f) -> uni (Esc a) -> uni (Esc (f a)) #

Apply a type constructor to an argument.

matchUniApply #

Arguments

:: uni tb

The type.

-> r

What to return if the type is not an application.

-> (forall k l (f :: k -> l) a. tb ~ Esc (f a) => uni (Esc f) -> uni (Esc a) -> r)

The continuation taking a function and an argument.

-> r 

Deconstruct a type application into the function and the argument and feed them to the continuation. If the type is not an application, then return the default value.

Instances

Instances details
HasUniApply DefaultUni # 
Instance details

Defined in PlutusCore.Default.Universe

Methods

uniApply :: forall k l (f :: k -> l) (a :: k). DefaultUni (Esc f) -> DefaultUni (Esc a) -> DefaultUni (Esc (f a)) #

matchUniApply :: DefaultUni tb -> r -> (forall k l (f :: k -> l) (a :: k). tb ~ Esc (f a) => DefaultUni (Esc f) -> DefaultUni (Esc a) -> r) -> r #

checkStar :: forall uni a (x :: a). Typeable a => uni (Esc x) -> Maybe (a :~: Type) #

Check if the kind of the given type from the universe is Type.

withApplicable :: forall (a :: Type) (ab :: Type) f x uni m r. (Typeable ab, Typeable a, MonadPlus m) => uni (Esc (f :: ab)) -> uni (Esc (x :: a)) -> (forall (b :: Type). (Typeable b, ab ~ (a -> b)) => m r) -> m r #

Check if one type from the universe can be applied to another (i.e. check that the expected kind of the argument matches the actual one) and call the continuation in the refined context. Fail with mzero otherwise.

tryUniApply :: (MonadPlus m, HasUniApply uni) => SomeTypeIn (Kinded uni) -> SomeTypeIn (Kinded uni) -> m (SomeTypeIn (Kinded uni)) #

Apply a type constructor to an argument, provided kinds match.

class GShow (t :: k -> Type) where #

Show-like class for 1-type-parameter GADTs. GShow t => ... is equivalent to something like (forall a. Show (t a)) => .... The easiest way to create instances would probably be to write (or derive) an instance Show (T a), and then simply say:

instance GShow t where gshowsPrec = defaultGshowsPrec

Methods

gshowsPrec :: forall (a :: k). GOrdering a a0 -> ShowS #

(GShow a, GShow b) => GShow (Product a b :: k -> Type)
>>> gshow (Pair Refl Refl :: Product ((:~:) Int) ((:~:) Int) Int)
"Pair Refl Refl"
Instance details

Defined in Data.GADT.Internal

Methods

gshowsPrec :: forall (a0 :: k0). Int -> Product a b a0 -> ShowS #

(GShow a, GShow b) => GShow (Sum a b :: k -> Type)
>>> gshow (InL Refl :: Sum ((:~:) Int) ((:~:) Bool) Int)
"InL Refl"
Instance details

Defined in Data.GADT.Internal

Methods

gshowsPrec :: forall (a0 :: k0). Int -> (a :~~: a0) -> ShowS #

(GShow a, GShow b) => GShow (a :*: b :: k -> Type)
>>> gshow (Pair Refl Refl :: Product ((:~:) Int) ((:~:) Int) Int)
"Refl :*: Refl"

Since: some-1.0.4

Instance details

Defined in Data.GADT.Internal

Methods

gshowsPrec :: forall (a0 :: k0). Int -> (a :*: b) a0 -> ShowS #

(GShow a, GShow b) => GShow (a :+: b :: k -> Type)
>>> gshow (L1 Refl :: ((:~:) Int :+: (:~:) Bool) Int)
"L1 Refl"

Since: some-1.0.4

Instance details

Defined in Data.GADT.Internal

Methods

gshowsPrec :: forall (a0 :: k0). Int -> (a :+: b) a0 -> ShowS #

gshow :: forall {k} t (a :: k). GShow t => t a -> String #

class GEq (f :: k -> Type) where #

A class for type-contexts which contain enough information to (at least in some cases) decide the equality of types occurring within them.

This class is sometimes confused with TestEquality from base. TestEquality only checks type equality.

Consider

>>> data Tag a where TagInt1 :: Tag Int; TagInt2 :: Tag Int

The correct TestEquality Tag instance is

>>> :{
instance TestEquality Tag where
    testEquality TagInt1 TagInt1 = Just Refl
    testEquality TagInt1 TagInt2 = Just Refl
    testEquality TagInt2 TagInt1 = Just Refl
    testEquality TagInt2 TagInt2 = Just Refl
:}

While we can define

instance GEq Tag where
   geq = testEquality

this will mean we probably want to have

instance Eq Tag where
   _ == _ = True

Note: In the future version of some package (to be released around GHC-9.6 / 9.8) the forall a. Eq (f a) constraint will be added as a constraint to GEq, with a law relating GEq and Eq:

geq x y = Just Refl   ⇒  x == y = True        ∀ (x :: f a) (y :: f b)
x == y                ≡  isJust (geq x y)     ∀ (x, y :: f a)

So, the more useful GEq Tag instance would differentiate between different constructors:

>>> :{
instance GEq Tag where
    geq TagInt1 TagInt1 = Just Refl
    geq TagInt1 TagInt2 = Nothing
    geq TagInt2 TagInt1 = Nothing
    geq TagInt2 TagInt2 = Just Refl
:}

which is consistent with a derived Eq instance for Tag

>>> deriving instance Eq (Tag a)

Note that even if a ~ b, the geq (x :: f a) (y :: f b) may be Nothing (when value terms are inequal).

The consistency of GEq and Eq is easy to check by exhaustion:

>>> let checkFwdGEq :: (forall a. Eq (f a), GEq f) => f a -> f b -> Bool; checkFwdGEq x y = case geq x y of Just Refl -> x == y; Nothing -> True
>>> (checkFwdGEq TagInt1 TagInt1, checkFwdGEq TagInt1 TagInt2, checkFwdGEq TagInt2 TagInt1, checkFwdGEq TagInt2 TagInt2)
(True,True,True,True)
>>> let checkBwdGEq :: (Eq (f a), GEq f) => f a -> f a -> Bool; checkBwdGEq x y = if x == y then isJust (geq x y) else isNothing (geq x y)
>>> (checkBwdGEq TagInt1 TagInt1, checkBwdGEq TagInt1 TagInt2, checkBwdGEq TagInt2 TagInt1, checkBwdGEq TagInt2 TagInt2)
(True,True,True,True)

Methods

geq :: forall (a :: k) (b :: k). f a -> f b -> Maybe (a :~: b) #

Produce a witness of type-equality, if one exists.

A handy idiom for using this would be to pattern-bind in the Maybe monad, eg.:

extract :: GEq tag => tag a -> DSum tag -> Maybe a
extract t1 (t2 :=> x) = do
    Refl <- geq t1 t2
    return x

Or in a list comprehension:

extractMany :: GEq tag => tag a -> [DSum tag] -> [a]
extractMany t1 things = [ x | (t2 :=> x) <- things, Refl <- maybeToList (geq t1 t2)]

(Making use of the DSum type from Data.Dependent.Sum in both examples)

Instances

Instances details
GEq Data.GADT.Internal

Methods

geq :: forall (a :: k0) (b :: k0). (f :+: g) a -> (f :+: g) b -> Maybe (a :~: b) #

defaultEq :: forall {k} f (a :: k) (b :: k). GEq f => f a -> f b -> Bool #

If f has a GEq instance, this function makes a suitable default implementation of (==).

data (a :: k) :~: (b :: k) where infix 4 #

Propositional equality. If a :~: b is inhabited by some terminating value, then the type a is the same as the type b. To use this equality in practice, pattern-match on the a :~: b to get out the Refl constructor; in the body of the pattern-match, the compiler knows that a ~ b.

Since: base-4.7.0.0

Constructors

Refl :: forall {k} (a :: k). a :~: a 

Instances

Instances details
Data.GADT.Internal

Methods

gshowsPrec :: forall (a0 :: k0). Int -> (a :~: a0) -> ShowS #

NFData2 ((:~:) :: Type -> Type -> Type)

Since: deepseq-1.4.3.0

Instance details

Defined in Control.DeepSeq

Methods

liftRnf2 :: (a -> ()) -> (b -> ()) -> (a :~: b) -> () #

NFData1 ((:~:) a)

Since: deepseq-1.4.3.0

Instance details

Defined in Control.DeepSeq

Methods

liftRnf :: (a0 -> ()) -> (a :~: a0) -> () #

(a ~ b, Data a) => Data (a :~: b)

Since: base-4.7.0.0

Instance details

Defined in Data.Data

Methods

gfoldl :: (forall d b0. Data d => c (d -> b0) -> d -> c b0) -> (forall g. g -> c g) -> (a :~: b) -> c (a :~: b) #

gunfold :: (forall b0 r. Data b0 => c (b0 -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (a :~: b) #

toConstr :: (a :~: b) -> Constr #

dataTypeOf :: (a :~: b) -> DataType #

dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (a :~: b)) #

dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (a :~: b)) #

gmapT :: (forall b0. Data b0 => b0 -> b0) -> (a :~: b) -> a :~: b #

gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> (a :~: b) -> r #

gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> (a :~: b) -> r #

gmapQ :: (forall d. Data d => d -> u) -> (a :~: b) -> [u] #

gmapQi :: Int -> (forall d. Data d => d -> u) -> (a :~: b) -> u #

gmapM :: Monad m => (forall d. Data d => d -> m d) -> (a :~: b) -> m (a :~: b) #

gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> (a :~: b) -> m (a :~: b) #

gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> (a :~: b) -> m (a :~: b) #

a ~ b => Bounded (a :~: b)

Since: base-4.7.0.0

Instance details

Defined in Data.Type.Equality

Methods

minBound :: a :~: b #

maxBound :: a :~: b #

a ~ b => Enum (a :~: b)

Since: base-4.7.0.0

Instance details

Defined in Data.Type.Equality

Methods

succ :: (a :~: b) -> a :~: b #

pred :: (a :~: b) -> a :~: b #

toEnum :: Int -> a :~: b #

fromEnum :: (a :~: b) -> Int #

enumFrom :: (a :~: b) -> [a :~: b] #

enumFromThen :: (a :~: b) -> (a :~: b) -> [a :~: b] #

enumFromTo :: (a :~: b) -> (a :~: b) -> [a :~: b] #

enumFromThenTo :: (a :~: b) -> (a :~: b) -> (a :~: b) -> [a :~: b] #

a ~ b => Read (a :~: b)

Since: base-4.7.0.0

Instance details

Defined in Data.Type.Equality

Methods

readsPrec :: Int -> ReadS (a :~: b) #

readList :: ReadS [a :~: b] #

readPrec :: ReadPrec (a :~: b) #

readListPrec :: ReadPrec [a :~: b] #

Show (a :~: b)

Since: base-4.7.0.0

Instance details

Defined in Data.Type.Equality

Methods

showsPrec :: Int -> (a :~: b) -> ShowS #

show :: (a :~: b) -> String #

showList :: [a :~: b] -> ShowS #

NFData (a :~: b)

Since: deepseq-1.4.3.0

Instance details

Defined in Control.DeepSeq

Methods

rnf :: (a :~: b) -> () #

Eq (a :~: b)

Since: base-4.7.0.0

Instance details

Defined in Data.Type.Equality

Methods

(==) :: (a :~: b) -> (a :~: b) -> Bool #

(/=) :: (a :~: b) -> (a :~: b) -> Bool #

Ord (a :~: b)

Since: base-4.7.0.0

Instance details

Defined in Data.Type.Equality

Methods

compare :: (a :~: b) -> (a :~: b) -> Ordering #

(<) :: (a :~: b) -> (a :~: b) -> Bool #

(<=) :: (a :~: b) -> (a :~: b) -> Bool #

(>) :: (a :~: b) -> (a :~: b) -> Bool #

(>=) :: (a :~: b) -> (a :~: b) -> Bool #

max :: (a :~: b) -> (a :~: b) -> a :~: b #

min :: (a :~: b) -> (a :~: b) -> a :~: b #

data DSum (tag :: k -> Type) (f :: k -> Type) #

A basic dependent sum type where the first component is a tag that specifies the type of the second. For example, think of a GADT such as:

data Tag a where
   AString :: Tag String
   AnInt   :: Tag Int
   Rec     :: Tag (DSum Tag Identity)

Then we can write expressions where the RHS of (:=>) has different types depending on the Tag constructor used. Here are some expressions of type DSum Tag Identity:

AString :=> Identity "hello!"
AnInt   :=> Identity 42

Often, the f we choose has an Applicative instance, and we can use the helper function (==>). The following expressions all have the type Applicative f => DSum Tag f:

AString ==> "hello!"
AnInt   ==> 42

We can write functions that consume DSum Tag f values by matching, such as:

toString :: DSum Tag Identity -> String
toString (AString :=> Identity str) = str
toString (AnInt   :=> Identity int) = show int
toString (Rec     :=> Identity sum) = toString sum

The (:=>) constructor and (==>) helper are chosen to resemble the (key => value) construction for dictionary entries in many dynamic languages. The :=> and ==> operators have very low precedence and bind to the right, making repeated use of these operators behave as you'd expect:

-- Parses as: Rec ==> (AnInt ==> (3 + 4))
-- Has type: Applicative f => DSum Tag f
Rec ==> AnInt ==> 3 + 4

The precedence of these operators is just above that of $, so foo bar $ AString ==> "eep" is equivalent to foo bar (AString ==> "eep").

To use the Eq, Ord, Read, and Show instances for DSum tag f, you will need an ArgDict instance for your tag type. Use deriveArgDict from the constraints-extras package to generate this instance.

Constructors

!(tag a) :=> (f a) infixr 1 

Instances

Instances details
(Data.Dependent.Sum

Methods

compare :: DSum tag f -> DSum tag f -> Ordering #

(<) :: DSum tag f -> DSum tag f -> Bool #

(<=) :: DSum tag f -> DSum tag f -> Bool #

(>) :: DSum tag f -> DSum tag f -> Bool #

(>=) :: DSum tag f -> DSum tag f -> Bool #

max :: DSum tag f -> DSum tag f -> DSum tag f #

min :: DSum tag f -> DSum tag f -> DSum tag f #