-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Convenient imperative eDSL over Lorentz. -- -- Syntax and implementation of Indigo eDSL. @package indigo @version 0.4 -- | This module is intended to be imported instead of -- morley-prelude by Backend Indigo modules. -- -- This only serves the purpose of listing hiding rules once and -- avoid boilerplate. module Indigo.Backend.Prelude -- | Append two lists, i.e., -- --
-- [x1, ..., xm] ++ [y1, ..., yn] == [x1, ..., xm, y1, ..., yn] -- [x1, ..., xm] ++ [y1, ...] == [x1, ..., xm, y1, ...] ---- -- If the first list is not finite, the result is the first list. (++) :: [a] -> [a] -> [a] infixr 5 ++ -- | The value of seq a b is bottom if a is bottom, and -- otherwise equal to b. In other words, it evaluates the first -- argument a to weak head normal form (WHNF). seq is -- usually introduced to improve performance by avoiding unneeded -- laziness. -- -- A note on evaluation order: the expression seq a b does -- not guarantee that a will be evaluated before -- b. The only guarantee given by seq is that the both -- a and b will be evaluated before seq -- returns a value. In particular, this means that b may be -- evaluated before a. If you need to guarantee a specific order -- of evaluation, you must use the function pseq from the -- "parallel" package. seq :: a -> b -> b infixr 0 `seq` -- | O(n). filter, applied to a predicate and a list, returns -- the list of those elements that satisfy the predicate; i.e., -- --
-- filter p xs = [ x | x <- xs, p x] ---- --
-- >>> filter odd [1, 2, 3] -- [1,3] --filter :: (a -> Bool) -> [a] -> [a] -- | O(min(m,n)). zip takes two lists and returns a list of -- corresponding pairs. -- --
-- zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')] ---- -- If one input list is short, excess elements of the longer list are -- discarded: -- --
-- zip [1] ['a', 'b'] = [(1, 'a')] -- zip [1, 2] ['a'] = [(1, 'a')] ---- -- zip is right-lazy: -- --
-- zip [] _|_ = [] -- zip _|_ [] = _|_ ---- -- zip is capable of list fusion, but it is restricted to its -- first list argument and its resulting list. zip :: [a] -> [b] -> [(a, b)] -- | Extract the first component of a pair. fst :: (a, b) -> a -- | Extract the second component of a pair. snd :: (a, b) -> b -- | otherwise is defined as the value True. It helps to make -- guards more readable. eg. -- --
-- f x | x < 0 = ... -- | otherwise = ... --otherwise :: Bool -- | Application operator. This operator is redundant, since ordinary -- application (f x) means the same as (f $ x). -- However, $ has low, right-associative binding precedence, so it -- sometimes allows parentheses to be omitted; for example: -- --
-- f $ g $ h x = f (g (h x)) ---- -- It is also useful in higher-order situations, such as map -- ($ 0) xs, or zipWith ($) fs xs. -- -- Note that ($) is levity-polymorphic in its result -- type, so that foo $ True where foo :: Bool -> -- Int# is well-typed. ($) :: forall (r :: RuntimeRep) a (b :: TYPE r). (a -> b) -> a -> b infixr 0 $ -- | general coercion from integral types fromIntegral :: (Integral a, Num b) => a -> b -- | general coercion to fractional types realToFrac :: (Real a, Fractional b) => a -> b -- | Conditional failure of Alternative computations. Defined by -- --
-- guard True = pure () -- guard False = empty ---- --
-- >>> safeDiv 4 0 -- Nothing -- >>> safeDiv 4 2 -- Just 2 ---- -- A definition of safeDiv using guards, but not guard: -- --
-- safeDiv :: Int -> Int -> Maybe Int -- safeDiv x y | y /= 0 = Just (x `div` y) -- | otherwise = Nothing ---- -- A definition of safeDiv using guard and Monad -- do-notation: -- --
-- safeDiv :: Int -> Int -> Maybe Int -- safeDiv x y = do -- guard (y /= 0) -- return (x `div` y) --guard :: Alternative f => Bool -> f () -- | The join function is the conventional monad join operator. It -- is used to remove one level of monadic structure, projecting its bound -- argument into the outer level. -- --
-- atomically :: STM a -> IO a ---- -- is used to run STM transactions atomically. So, by specializing -- the types of atomically and join to -- --
-- atomically :: STM (IO b) -> IO (IO b) -- join :: IO (IO b) -> IO b ---- -- we can compose them as -- --
-- join . atomically :: STM (IO b) -> IO b ---- -- to run an STM transaction and the IO action it returns. join :: Monad m => m (m a) -> m a -- | The Bounded class is used to name the upper and lower limits of -- a type. Ord is not a superclass of Bounded since types -- that are not totally ordered may also have upper and lower bounds. -- -- The Bounded class may be derived for any enumeration type; -- minBound is the first constructor listed in the data -- declaration and maxBound is the last. Bounded may also -- be derived for single-constructor datatypes whose constituent types -- are in Bounded. class Bounded a minBound :: Bounded a => a maxBound :: Bounded a => a -- | Class Enum defines operations on sequentially ordered types. -- -- The enumFrom... methods are used in Haskell's translation of -- arithmetic sequences. -- -- Instances of Enum may be derived for any enumeration type -- (types whose constructors have no fields). The nullary constructors -- are assumed to be numbered left-to-right by fromEnum from -- 0 through n-1. See Chapter 10 of the Haskell -- Report for more details. -- -- For any type that is an instance of class Bounded as well as -- Enum, the following should hold: -- --
-- enumFrom x = enumFromTo x maxBound -- enumFromThen x y = enumFromThenTo x y bound -- where -- bound | fromEnum y >= fromEnum x = maxBound -- | otherwise = minBound --class Enum a -- | the successor of a value. For numeric types, succ adds 1. succ :: Enum a => a -> a -- | the predecessor of a value. For numeric types, pred subtracts -- 1. pred :: Enum a => a -> a -- | Convert from an Int. toEnum :: Enum a => Int -> a -- | Convert to an Int. It is implementation-dependent what -- fromEnum returns when applied to a value that is too large to -- fit in an Int. fromEnum :: Enum a => a -> Int -- | Used in Haskell's translation of [n..] with [n..] = -- enumFrom n, a possible implementation being enumFrom n = n : -- enumFrom (succ n). For example: -- --
enumFrom 4 :: [Integer] = [4,5,6,7,...]
enumFrom 6 :: [Int] = [6,7,8,9,...,maxBound :: -- Int]
enumFromThen 4 6 :: [Integer] = [4,6,8,10...]
enumFromThen 6 2 :: [Int] = [6,2,-2,-6,...,minBound :: -- Int]
enumFromTo 6 10 :: [Int] = [6,7,8,9,10]
enumFromTo 42 1 :: [Integer] = []
enumFromThenTo 4 2 -6 :: [Integer] = -- [4,2,0,-2,-4,-6]
enumFromThenTo 6 8 2 :: [Int] = []
-- (x `quot` y)*y + (x `rem` y) == x --rem :: Integral a => a -> a -> a -- | integer division truncated toward negative infinity div :: Integral a => a -> a -> a -- | integer modulus, satisfying -- --
-- (x `div` y)*y + (x `mod` y) == x --mod :: Integral a => a -> a -> a -- | simultaneous quot and rem quotRem :: Integral a => a -> a -> (a, a) -- | simultaneous div and mod divMod :: Integral a => a -> a -> (a, a) -- | conversion to Integer toInteger :: Integral a => a -> Integer infixl 7 `quot` infixl 7 `rem` infixl 7 `div` infixl 7 `mod` -- | The Monad class defines the basic operations over a -- monad, a concept from a branch of mathematics known as -- category theory. From the perspective of a Haskell programmer, -- however, it is best to think of a monad as an abstract datatype -- of actions. Haskell's do expressions provide a convenient -- syntax for writing monadic expressions. -- -- Instances of Monad should satisfy the following: -- --
-- abs x * signum x == x ---- -- For real numbers, the signum is either -1 (negative), -- 0 (zero) or 1 (positive). signum :: Num a => a -> a -- | Conversion from an Integer. An integer literal represents the -- application of the function fromInteger to the appropriate -- value of type Integer, so such literals have type -- (Num a) => a. fromInteger :: Num a => Integer -> a infixl 6 + infixl 7 * infixl 6 - -- | The Ord class is used for totally ordered datatypes. -- -- Instances of Ord can be derived for any user-defined datatype -- whose constituent types are in Ord. The declared order of the -- constructors in the data declaration determines the ordering in -- derived Ord instances. The Ordering datatype allows a -- single comparison to determine the precise ordering of two objects. -- -- The Haskell Report defines no laws for Ord. However, -- <= is customarily expected to implement a non-strict partial -- order and have the following properties: -- --
-- infixr 5 :^: -- data Tree a = Leaf a | Tree a :^: Tree a ---- -- the derived instance of Read in Haskell 2010 is equivalent to -- --
-- instance (Read a) => Read (Tree a) where
--
-- readsPrec d r = readParen (d > app_prec)
-- (\r -> [(Leaf m,t) |
-- ("Leaf",s) <- lex r,
-- (m,t) <- readsPrec (app_prec+1) s]) r
--
-- ++ readParen (d > up_prec)
-- (\r -> [(u:^:v,w) |
-- (u,s) <- readsPrec (up_prec+1) r,
-- (":^:",t) <- lex s,
-- (v,w) <- readsPrec (up_prec+1) t]) r
--
-- where app_prec = 10
-- up_prec = 5
--
--
-- Note that right-associativity of :^: is unused.
--
-- The derived instance in GHC is equivalent to
--
-- -- instance (Read a) => Read (Tree a) where -- -- readPrec = parens $ (prec app_prec $ do -- Ident "Leaf" <- lexP -- m <- step readPrec -- return (Leaf m)) -- -- +++ (prec up_prec $ do -- u <- step readPrec -- Symbol ":^:" <- lexP -- v <- step readPrec -- return (u :^: v)) -- -- where app_prec = 10 -- up_prec = 5 -- -- readListPrec = readListPrecDefault ---- -- Why do both readsPrec and readPrec exist, and why does -- GHC opt to implement readPrec in derived Read instances -- instead of readsPrec? The reason is that readsPrec is -- based on the ReadS type, and although ReadS is mentioned -- in the Haskell 2010 Report, it is not a very efficient parser data -- structure. -- -- readPrec, on the other hand, is based on a much more efficient -- ReadPrec datatype (a.k.a "new-style parsers"), but its -- definition relies on the use of the RankNTypes language -- extension. Therefore, readPrec (and its cousin, -- readListPrec) are marked as GHC-only. Nevertheless, it is -- recommended to use readPrec instead of readsPrec -- whenever possible for the efficiency improvements it brings. -- -- As mentioned above, derived Read instances in GHC will -- implement readPrec instead of readsPrec. The default -- implementations of readsPrec (and its cousin, readList) -- will simply use readPrec under the hood. If you are writing a -- Read instance by hand, it is recommended to write it like so: -- --
-- instance Read T where -- readPrec = ... -- readListPrec = readListPrecDefault --class Read a class (Num a, Ord a) => Real a -- | the rational equivalent of its real argument with full precision toRational :: Real a => a -> Rational -- | Extracting components of fractions. class (Real a, Fractional a) => RealFrac a -- | The function properFraction takes a real fractional number -- x and returns a pair (n,f) such that x = -- n+f, and: -- --
-- infixr 5 :^: -- data Tree a = Leaf a | Tree a :^: Tree a ---- -- the derived instance of Show is equivalent to -- --
-- instance (Show a) => Show (Tree a) where -- -- showsPrec d (Leaf m) = showParen (d > app_prec) $ -- showString "Leaf " . showsPrec (app_prec+1) m -- where app_prec = 10 -- -- showsPrec d (u :^: v) = showParen (d > up_prec) $ -- showsPrec (up_prec+1) u . -- showString " :^: " . -- showsPrec (up_prec+1) v -- where up_prec = 5 ---- -- Note that right-associativity of :^: is ignored. For example, -- --
-- fail s >>= f = fail s ---- -- If your Monad is also MonadPlus, a popular definition is -- --
-- fail _ = mzero --class Monad m => MonadFail (m :: Type -> Type) fail :: MonadFail m => String -> m a -- | Class for string-like datastructures; used by the overloaded string -- extension (-XOverloadedStrings in GHC). class IsString a fromString :: IsString a => String -> a -- | A functor with application, providing operations to -- --
-- (<*>) = liftA2 id ---- --
-- liftA2 f x y = f <$> x <*> y ---- -- Further, any definition must satisfy the following: -- --
pure id <*> v = -- v
pure (.) <*> u -- <*> v <*> w = u <*> (v -- <*> w)
pure f <*> -- pure x = pure (f x)
u <*> pure y = -- pure ($ y) <*> u
-- forall x y. p (q x y) = f x . g y ---- -- it follows from the above that -- --
-- liftA2 p (liftA2 q u v) = liftA2 f u . liftA2 g v ---- -- If f is also a Monad, it should satisfy -- -- -- -- (which implies that pure and <*> satisfy the -- applicative functor laws). class Functor f => Applicative (f :: Type -> Type) -- | Lift a value. pure :: Applicative f => a -> f a -- | Sequential application. -- -- A few functors support an implementation of <*> that is -- more efficient than the default one. (<*>) :: Applicative f => f (a -> b) -> f a -> f b -- | Lift a binary function to actions. -- -- Some functors support an implementation of liftA2 that is more -- efficient than the default one. In particular, if fmap is an -- expensive operation, it is likely better to use liftA2 than to -- fmap over the structure and then use <*>. liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c -- | Sequence actions, discarding the value of the first argument. (*>) :: Applicative f => f a -> f b -> f b -- | Sequence actions, discarding the value of the second argument. (<*) :: Applicative f => f a -> f b -> f a infixl 4 <*> infixl 4 *> infixl 4 <* -- | Data structures that can be folded. -- -- For example, given a data type -- --
-- data Tree a = Empty | Leaf a | Node (Tree a) a (Tree a) ---- -- a suitable instance would be -- --
-- instance Foldable Tree where -- foldMap f Empty = mempty -- foldMap f (Leaf x) = f x -- foldMap f (Node l k r) = foldMap f l `mappend` f k `mappend` foldMap f r ---- -- This is suitable even for abstract types, as the monoid is assumed to -- satisfy the monoid laws. Alternatively, one could define -- foldr: -- --
-- instance Foldable Tree where -- foldr f z Empty = z -- foldr f z (Leaf x) = f x z -- foldr f z (Node l k r) = foldr f (f k (foldr f z r)) l ---- -- Foldable instances are expected to satisfy the following -- laws: -- --
-- foldr f z t = appEndo (foldMap (Endo . f) t ) z ---- --
-- foldl f z t = appEndo (getDual (foldMap (Dual . Endo . flip f) t)) z ---- --
-- fold = foldMap id ---- --
-- length = getSum . foldMap (Sum . const 1) ---- -- sum, product, maximum, and minimum -- should all be essentially equivalent to foldMap forms, such -- as -- --
-- sum = getSum . foldMap Sum ---- -- but may be less defined. -- -- If the type is also a Functor instance, it should satisfy -- --
-- foldMap f = fold . fmap f ---- -- which implies that -- --
-- foldMap f . fmap g = foldMap (f . g) --class Foldable (t :: Type -> Type) -- | Functors representing data structures that can be traversed from left -- to right. -- -- A definition of traverse must satisfy the following laws: -- --
-- t :: (Applicative f, Applicative g) => f a -> g a ---- -- preserving the Applicative operations, i.e. -- --
-- t (pure x) = pure x -- t (f <*> x) = t f <*> t x ---- -- and the identity functor Identity and composition functors -- Compose are from Data.Functor.Identity and -- Data.Functor.Compose. -- -- (The naturality law is implied by parametricity.) -- -- Instances are similar to Functor, e.g. given a data type -- --
-- data Tree a = Empty | Leaf a | Node (Tree a) a (Tree a) ---- -- a suitable instance would be -- --
-- instance Traversable Tree where -- traverse f Empty = pure Empty -- traverse f (Leaf x) = Leaf <$> f x -- traverse f (Node l k r) = Node <$> traverse f l <*> f k <*> traverse f r ---- -- This is suitable even for abstract types, as the laws for -- <*> imply a form of associativity. -- -- The superclass instances should satisfy the following: -- --
-- from . to ≡ id -- to . from ≡ id --class Generic a -- | This class gives the integer associated with a type-level natural. -- There are instances of the class for every concrete literal: 0, 1, 2, -- etc. class KnownNat (n :: Nat) class IsLabel (x :: Symbol) a fromLabel :: IsLabel x a => a -- | The class of semigroups (types with an associative binary operation). -- -- Instances should satisfy the following: -- -- class Semigroup a -- | An associative operation. (<>) :: Semigroup a => a -> a -> a -- | Reduce a non-empty list with <> -- -- The default definition should be sufficient, but this can be -- overridden for efficiency. sconcat :: Semigroup a => NonEmpty a -> a -- | Repeat a value n times. -- -- Given that this works on a Semigroup it is allowed to fail if -- you request 0 or fewer repetitions, and the default definition will do -- so. -- -- By making this a member of the class, idempotent semigroups and -- monoids can upgrade this to execute in O(1) by picking -- stimes = stimesIdempotent or stimes = -- stimesIdempotentMonoid respectively. stimes :: (Semigroup a, Integral b) => b -> a -> a infixr 6 <> -- | The class of monoids (types with an associative binary operation that -- has an identity). Instances should satisfy the following: -- --
-- >>> 2^100 :: Natural -- 1267650600228229401496703205376 ---- -- Operations whose result would be negative throw -- (Underflow :: ArithException), -- --
-- >>> -1 :: Natural -- *** Exception: arithmetic underflow --data Natural -- | The Maybe type encapsulates an optional value. A value of type -- Maybe a either contains a value of type a -- (represented as Just a), or it is empty (represented -- as Nothing). Using Maybe is a good way to deal with -- errors or exceptional cases without resorting to drastic measures such -- as error. -- -- The Maybe type is also a monad. It is a simple kind of error -- monad, where all errors are represented by Nothing. A richer -- error monad can be built using the Either type. data Maybe a Nothing :: Maybe a Just :: a -> Maybe a data Ordering LT :: Ordering EQ :: Ordering GT :: Ordering -- | Rational numbers, with numerator and denominator of some -- Integral type. -- -- Note that Ratio's instances inherit the deficiencies from the -- type parameter's. For example, Ratio Natural's Num -- instance has similar problems to Natural's. data Ratio a (:%) :: !a -> !a -> Ratio a -- | Arbitrary-precision rational numbers, represented as a ratio of two -- Integer values. A rational number may be constructed using the -- % operator. type Rational = Ratio Integer -- | A value of type IO a is a computation which, when -- performed, does some I/O before returning a value of type a. -- -- There is really only one way to "perform" an I/O action: bind it to -- Main.main in your program. When your program is run, the I/O -- will be performed. It isn't possible to perform I/O from an arbitrary -- function, unless that function is itself in the IO monad and -- called at some point, directly or indirectly, from Main.main. -- -- IO is a monad, so IO actions can be combined using -- either the do-notation or the >> and >>= -- operations from the Monad class. data IO a -- | A Word is an unsigned integral type, with the same size as -- Int. data Word -- | 8-bit unsigned integer type data Word8 -- | 16-bit unsigned integer type data Word16 -- | 32-bit unsigned integer type data Word32 -- | 64-bit unsigned integer type data Word64 -- | A value of type Ptr a represents a pointer to an -- object, or an array of objects, which may be marshalled to or from -- Haskell values of type a. -- -- The type a will often be an instance of class Storable -- which provides the marshalling operations. However this is not -- essential, and you can provide your own operations to access the -- pointer. For example you might write small foreign functions to get or -- set the fields of a C struct. data Ptr a -- | A value of type FunPtr a is a pointer to a function -- callable from foreign code. The type a will normally be a -- foreign type, a function type with zero or more arguments where -- --
-- foreign import ccall "stdlib.h &free" -- p_free :: FunPtr (Ptr a -> IO ()) ---- -- or a pointer to a Haskell function created using a wrapper stub -- declared to produce a FunPtr of the correct type. For example: -- --
-- type Compare = Int -> Int -> Bool -- foreign import ccall "wrapper" -- mkCompare :: Compare -> IO (FunPtr Compare) ---- -- Calls to wrapper stubs like mkCompare allocate storage, which -- should be released with freeHaskellFunPtr when no longer -- required. -- -- To convert FunPtr values to corresponding Haskell functions, -- one can define a dynamic stub for the specific foreign type, -- e.g. -- --
-- type IntFunction = CInt -> IO () -- foreign import ccall "dynamic" -- mkFun :: FunPtr IntFunction -> IntFunction --data FunPtr a -- | The Either type represents values with two possibilities: a -- value of type Either a b is either Left -- a or Right b. -- -- The Either type is sometimes used to represent a value which is -- either correct or an error; by convention, the Left constructor -- is used to hold an error value and the Right constructor is -- used to hold a correct value (mnemonic: "right" also means "correct"). -- --
-- >>> let s = Left "foo" :: Either String Int -- -- >>> s -- Left "foo" -- -- >>> let n = Right 3 :: Either String Int -- -- >>> n -- Right 3 -- -- >>> :type s -- s :: Either String Int -- -- >>> :type n -- n :: Either String Int ---- -- The fmap from our Functor instance will ignore -- Left values, but will apply the supplied function to values -- contained in a Right: -- --
-- >>> let s = Left "foo" :: Either String Int -- -- >>> let n = Right 3 :: Either String Int -- -- >>> fmap (*2) s -- Left "foo" -- -- >>> fmap (*2) n -- Right 6 ---- -- The Monad instance for Either allows us to chain -- together multiple actions which may fail, and fail overall if any of -- the individual steps failed. First we'll write a function that can -- either parse an Int from a Char, or fail. -- --
-- >>> import Data.Char ( digitToInt, isDigit )
--
-- >>> :{
-- let parseEither :: Char -> Either String Int
-- parseEither c
-- | isDigit c = Right (digitToInt c)
-- | otherwise = Left "parse error"
--
-- >>> :}
--
--
-- The following should work, since both '1' and '2'
-- can be parsed as Ints.
--
--
-- >>> :{
-- let parseMultiple :: Either String Int
-- parseMultiple = do
-- x <- parseEither '1'
-- y <- parseEither '2'
-- return (x + y)
--
-- >>> :}
--
--
-- -- >>> parseMultiple -- Right 3 ---- -- But the following should fail overall, since the first operation where -- we attempt to parse 'm' as an Int will fail: -- --
-- >>> :{
-- let parseMultiple :: Either String Int
-- parseMultiple = do
-- x <- parseEither 'm'
-- y <- parseEither '2'
-- return (x + y)
--
-- >>> :}
--
--
-- -- >>> parseMultiple -- Left "parse error" --data Either a b Left :: a -> Either a b Right :: b -> Either a b -- | The kind of constraints, like Show a data Constraint -- | Comparison of type-level naturals, as a function. type family CmpNat (a :: Nat) (b :: Nat) :: Ordering -- | Coercible is a two-parameter class that has instances for -- types a and b if the compiler can infer that they -- have the same representation. This class does not have regular -- instances; instead they are created on-the-fly during type-checking. -- Trying to manually declare an instance of Coercible is an -- error. -- -- Nevertheless one can pretend that the following three kinds of -- instances exist. First, as a trivial base-case: -- --
-- instance Coercible a a ---- -- Furthermore, for every type constructor there is an instance that -- allows to coerce under the type constructor. For example, let -- D be a prototypical type constructor (data or -- newtype) with three type arguments, which have roles -- nominal, representational resp. phantom. -- Then there is an instance of the form -- --
-- instance Coercible b b' => Coercible (D a b c) (D a b' c') ---- -- Note that the nominal type arguments are equal, the -- representational type arguments can differ, but need to have -- a Coercible instance themself, and the phantom type -- arguments can be changed arbitrarily. -- -- The third kind of instance exists for every newtype NT = MkNT -- T and comes in two variants, namely -- --
-- instance Coercible a T => Coercible a NT ---- --
-- instance Coercible T b => Coercible NT b ---- -- This instance is only usable if the constructor MkNT is in -- scope. -- -- If, as a library author of a type constructor like Set a, you -- want to prevent a user of your module to write coerce :: Set T -- -> Set NT, you need to set the role of Set's type -- parameter to nominal, by writing -- --
-- type role Set nominal ---- -- For more details about this feature, please refer to Safe -- Coercions by Joachim Breitner, Richard A. Eisenberg, Simon Peyton -- Jones and Stephanie Weirich. class a ~R# b => Coercible (a :: k) (b :: k) -- | CallStacks are a lightweight method of obtaining a partial -- call-stack at any point in the program. -- -- A function can request its call-site with the HasCallStack -- constraint. For example, we can define -- --
-- putStrLnWithCallStack :: HasCallStack => String -> IO () ---- -- as a variant of putStrLn that will get its call-site and -- print it, along with the string given as argument. We can access the -- call-stack inside putStrLnWithCallStack with -- callStack. -- --
-- putStrLnWithCallStack :: HasCallStack => String -> IO () -- putStrLnWithCallStack msg = do -- putStrLn msg -- putStrLn (prettyCallStack callStack) ---- -- Thus, if we call putStrLnWithCallStack we will get a -- formatted call-stack alongside our string. -- --
-- >>> putStrLnWithCallStack "hello" -- hello -- CallStack (from HasCallStack): -- putStrLnWithCallStack, called at <interactive>:2:1 in interactive:Ghci1 ---- -- GHC solves HasCallStack constraints in three steps: -- --
-- id x = x --id :: a -> a -- | Case analysis for the Either type. If the value is -- Left a, apply the first function to a; if it -- is Right b, apply the second function to b. -- --
-- >>> let s = Left "foo" :: Either String Int -- -- >>> let n = Right 3 :: Either String Int -- -- >>> either length (*2) s -- 3 -- -- >>> either length (*2) n -- 6 --either :: (a -> c) -> (b -> c) -> Either a b -> c -- | See examples in Control.Monad.Reader. Note, the partially -- applied function type (->) r is a simple reader monad. See -- the instance declaration below. class Monad m => MonadReader r (m :: Type -> Type) | m -> r -- | Retrieves the monad environment. ask :: MonadReader r m => m r -- | Executes a computation in a modified environment. local :: MonadReader r m => (r -> r) -> m a -> m a -- | Retrieves a function of the current environment. reader :: MonadReader r m => (r -> a) -> m a -- | Minimal definition is either both of get and put or -- just state class Monad m => MonadState s (m :: Type -> Type) | m -> s -- | Return the state from the internals of the monad. get :: MonadState s m => m s -- | Replace the state inside the monad. put :: MonadState s m => s -> m () -- | Embed a simple state action into the monad. state :: MonadState s m => (s -> (a, s)) -> m a -- | A space-efficient representation of a Word8 vector, supporting -- many efficient operations. -- -- A ByteString contains 8-bit bytes, or by using the operations -- from Data.ByteString.Char8 it can be interpreted as containing -- 8-bit characters. data ByteString -- | An infix synonym for fmap. -- -- The name of this operator is an allusion to $. Note the -- similarities between their types: -- --
-- ($) :: (a -> b) -> a -> b -- (<$>) :: Functor f => (a -> b) -> f a -> f b ---- -- Whereas $ is function application, <$> is function -- application lifted over a Functor. -- --
-- >>> show <$> Nothing -- Nothing -- -- >>> show <$> Just 3 -- Just "3" ---- -- Convert from an Either Int Int to an -- Either Int String using show: -- --
-- >>> show <$> Left 17 -- Left 17 -- -- >>> show <$> Right 17 -- Right "17" ---- -- Double each element of a list: -- --
-- >>> (*2) <$> [1,2,3] -- [2,4,6] ---- -- Apply even to the second element of a pair: -- --
-- >>> even <$> (2,2) -- (2,True) --(<$>) :: Functor f => (a -> b) -> f a -> f b infixl 4 <$> -- | A String is a list of characters. String constants in Haskell -- are values of type String. type String = [Char] -- | The class of types that can be converted to a hash value. -- -- Minimal implementation: hashWithSalt. class Hashable a -- | Return a hash value for the argument, using the given salt. -- -- The general contract of hashWithSalt is: -- --
-- >>> const 42 "hello" -- 42 ---- --
-- >>> map (const 42) [0..3] -- [42,42,42,42] --const :: a -> b -> a -- | Function composition. (.) :: (b -> c) -> (a -> b) -> a -> c infixr 9 . -- | A map from keys to values. A map cannot contain duplicate keys; each -- key can map to at most one value. data HashMap k v -- | A Map from keys k to values a. -- -- The Semigroup operation for Map is union, which -- prefers values from the left operand. If m1 maps a key -- k to a value a1, and m2 maps the same key -- to a different value a2, then their union m1 <> -- m2 maps k to a1. data Map k a -- | A handle managing output to the Haskell program's standard output -- channel. stdout :: Handle -- | Haskell defines operations to read and write characters from and to -- files, represented by values of type Handle. Each value of -- this type is a handle: a record used by the Haskell run-time -- system to manage I/O with file system objects. A handle has at -- least the following properties: -- --
-- mzero >>= f = mzero -- v >> mzero = mzero ---- -- The default definition is -- --
-- mzero = empty --mzero :: MonadPlus m => m a -- | An associative operation. The default definition is -- --
-- mplus = (<|>) --mplus :: MonadPlus m => m a -> m a -> m a -- | Right-to-left composition of functors. The composition of applicative -- functors is always applicative, but the composition of monads is not -- always a monad. newtype Compose (f :: k -> Type) (g :: k1 -> k) (a :: k1) Compose :: f (g a) -> Compose (f :: k -> Type) (g :: k1 -> k) (a :: k1) [getCompose] :: Compose (f :: k -> Type) (g :: k1 -> k) (a :: k1) -> f (g a) infixr 9 `Compose` infixr 9 `Compose` -- | If Void is uninhabited then any Functor that holds only -- values of type Void is holding no values. vacuous :: Functor f => f Void -> f a -- | Since Void values logically don't exist, this witnesses the -- logical reasoning tool of "ex falso quodlibet". -- --
-- >>> let x :: Either Void Int; x = Right 5
--
-- >>> :{
-- case x of
-- Right r -> r
-- Left l -> absurd l
-- :}
-- 5
--
absurd :: Void -> a
-- | Uninhabited data type
data Void
-- | Repeat a value n times.
--
-- -- mtimesDefault n a = a <> a <> ... <> a -- using <> (n-1) times ---- -- Implemented using stimes and mempty. -- -- This is a suitable definition for an mtimes member of -- Monoid. mtimesDefault :: (Integral b, Monoid a) => b -> a -> a -- | A generalization of cycle to an arbitrary Semigroup. May -- fail to terminate for some values in some semigroups. cycle1 :: Semigroup m => m -> m -- | Provide a Semigroup for an arbitrary Monoid. -- -- NOTE: This is not needed anymore since Semigroup became -- a superclass of Monoid in base-4.11 and this newtype be -- deprecated at some point in the future. data WrappedMonoid m -- | Option is effectively Maybe with a better instance of -- Monoid, built off of an underlying Semigroup instead of -- an underlying Monoid. -- -- Ideally, this type would not exist at all and we would just fix the -- Monoid instance of Maybe. -- -- In GHC 8.4 and higher, the Monoid instance for Maybe has -- been corrected to lift a Semigroup instance instead of a -- Monoid instance. Consequently, this type is no longer useful. -- It will be marked deprecated in GHC 8.8 and removed in GHC 8.10. newtype Option a Option :: Maybe a -> Option a [getOption] :: Option a -> Maybe a -- | The sortWith function sorts a list of elements using the user -- supplied function to project something out of each element sortWith :: Ord b => (a -> b) -> [a] -> [a] -- | A bifunctor is a type constructor that takes two type arguments and is -- a functor in both arguments. That is, unlike with -- Functor, a type constructor such as Either does not need -- to be partially applied for a Bifunctor instance, and the -- methods in this class permit mapping functions over the Left -- value or the Right value, or both at the same time. -- -- Formally, the class Bifunctor represents a bifunctor from -- Hask -> Hask. -- -- Intuitively it is a bifunctor where both the first and second -- arguments are covariant. -- -- You can define a Bifunctor by either defining bimap or -- by defining both first and second. -- -- If you supply bimap, you should ensure that: -- --
-- bimap id id ≡ id ---- -- If you supply first and second, ensure: -- --
-- first id ≡ id -- second id ≡ id ---- -- If you supply both, you should also ensure: -- --
-- bimap f g ≡ first f . second g ---- -- These ensure by parametricity: -- --
-- bimap (f . g) (h . i) ≡ bimap f h . bimap g i -- first (f . g) ≡ first f . first g -- second (f . g) ≡ second f . second g --class Bifunctor (p :: Type -> Type -> Type) -- | Map over both arguments at the same time. -- --
-- bimap f g ≡ first f . second g ---- --
-- >>> bimap toUpper (+1) ('j', 3)
-- ('J',4)
--
--
-- -- >>> bimap toUpper (+1) (Left 'j') -- Left 'J' ---- --
-- >>> bimap toUpper (+1) (Right 3) -- Right 4 --bimap :: Bifunctor p => (a -> b) -> (c -> d) -> p a c -> p b d -- | Map covariantly over the first argument. -- --
-- first f ≡ bimap f id ---- --
-- >>> first toUpper ('j', 3)
-- ('J',3)
--
--
-- -- >>> first toUpper (Left 'j') -- Left 'J' --first :: Bifunctor p => (a -> b) -> p a c -> p b c -- | Map covariantly over the second argument. -- --
-- second ≡ bimap id ---- --
-- >>> second (+1) ('j', 3)
-- ('j',4)
--
--
-- -- >>> second (+1) (Right 3) -- Right 4 --second :: Bifunctor p => (b -> c) -> p a b -> p a c -- | Extract everything except the last element of the stream. init :: NonEmpty a -> [a] -- | Extract the last element of the stream. last :: NonEmpty a -> a -- | Extract the possibly-empty tail of the stream. tail :: NonEmpty a -> [a] -- | Extract the first element of the stream. head :: NonEmpty a -> a -- | nonEmpty efficiently turns a normal list into a NonEmpty -- stream, producing Nothing if the input is empty. nonEmpty :: [a] -> Maybe (NonEmpty a) -- | Get a string representation of the current execution stack state. showStackTrace :: IO (Maybe String) -- | Get a trace of the current execution stack state. -- -- Returns Nothing if stack trace support isn't available on -- host machine. getStackTrace :: IO (Maybe [Location]) -- | Monads in which IO computations may be embedded. Any monad -- built by applying a sequence of monad transformers to the IO -- monad will be an instance of this class. -- -- Instances should satisfy the following laws, which state that -- liftIO is a transformer of monads: -- -- class Monad m => MonadIO (m :: Type -> Type) -- | Lift a computation from the IO monad. liftIO :: MonadIO m => IO a -> m a -- | Direct MonadPlus equivalent of filter. -- --
-- filter = ( mfilter :: (a -> Bool) -> [a] -> [a] ) ---- -- An example using mfilter with the Maybe monad: -- --
-- >>> mfilter odd (Just 1) -- Just 1 -- >>> mfilter odd (Just 2) -- Nothing --mfilter :: MonadPlus m => (a -> Bool) -> m a -> m a -- | Strict version of <$>. (<$!>) :: Monad m => (a -> b) -> m a -> m b infixl 4 <$!> -- | The reverse of when. unless :: Applicative f => Bool -> f () -> f () -- | Like replicateM, but discards the result. replicateM_ :: Applicative m => Int -> m a -> m () -- | replicateM n act performs the action n times, -- gathering the results. replicateM :: Applicative m => Int -> m a -> m [a] -- | Like foldM, but discards the result. foldM_ :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m () -- | The foldM function is analogous to foldl, except that -- its result is encapsulated in a monad. Note that foldM works -- from left-to-right over the list arguments. This could be an issue -- where (>>) and the `folded function' are not -- commutative. -- --
-- foldM f a1 [x1, x2, ..., xm] -- -- == -- -- do -- a2 <- f a1 x1 -- a3 <- f a2 x2 -- ... -- f am xm ---- -- If right-to-left evaluation is required, the input list should be -- reversed. -- -- Note: foldM is the same as foldlM foldM :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b -- | zipWithM_ is the extension of zipWithM which ignores the -- final result. zipWithM_ :: Applicative m => (a -> b -> m c) -> [a] -> [b] -> m () -- | The zipWithM function generalizes zipWith to arbitrary -- applicative functors. zipWithM :: Applicative m => (a -> b -> m c) -> [a] -> [b] -> m [c] -- | The mapAndUnzipM function maps its first argument over a list, -- returning the result as a pair of lists. This function is mainly used -- with complicated data structures or a state monad. mapAndUnzipM :: Applicative m => (a -> m (b, c)) -> [a] -> m ([b], [c]) -- | Repeat an action indefinitely. -- --
-- echoServer :: Socket -> IO () -- echoServer socket = forever $ do -- client <- accept socket -- forkFinally (echo client) (\_ -> hClose client) -- where -- echo :: Handle -> IO () -- echo client = forever $ -- hGetLine client >>= hPutStrLn client --forever :: Applicative f => f a -> f b -- | Right-to-left composition of Kleisli arrows. -- (>=>), with the arguments flipped. -- -- Note how this operator resembles function composition -- (.): -- --
-- (.) :: (b -> c) -> (a -> b) -> a -> c -- (<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c --(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c infixr 1 <=< -- | Left-to-right composition of Kleisli arrows. (>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c infixr 1 >=> -- | This generalizes the list-based filter function. filterM :: Applicative m => (a -> m Bool) -> [a] -> m [a] -- | This function may be used as a value for foldMap in a -- Foldable instance. -- --
-- foldMapDefault f ≡ getConst . traverse (Const . f) --foldMapDefault :: (Traversable t, Monoid m) => (a -> m) -> t a -> m -- | This function may be used as a value for fmap in a -- Functor instance, provided that traverse is defined. -- (Using fmapDefault with a Traversable instance defined -- only by sequenceA will result in infinite recursion.) -- --
-- fmapDefault f ≡ runIdentity . traverse (Identity . f) --fmapDefault :: Traversable t => (a -> b) -> t a -> t b -- | The mapAccumR function behaves like a combination of -- fmap and foldr; it applies a function to each element of -- a structure, passing an accumulating parameter from right to left, and -- returning a final value of this accumulator together with the new -- structure. mapAccumR :: Traversable t => (a -> b -> (a, c)) -> a -> t b -> (a, t c) -- | The mapAccumL function behaves like a combination of -- fmap and foldl; it applies a function to each element of -- a structure, passing an accumulating parameter from left to right, and -- returning a final value of this accumulator together with the new -- structure. mapAccumL :: Traversable t => (a -> b -> (a, c)) -> a -> t b -> (a, t c) -- | forM is mapM with its arguments flipped. For a version -- that ignores the results see forM_. forM :: (Traversable t, Monad m) => t a -> (a -> m b) -> m (t b) -- | One or none. optional :: Alternative f => f a -> f (Maybe a) -- | Lists, but with an Applicative functor based on zipping. newtype ZipList a ZipList :: [a] -> ZipList a [getZipList] :: ZipList a -> [a] -- | Fanout: send the input to both argument arrows and combine their -- output. -- -- The default definition may be overridden with a more efficient version -- if desired. (&&&) :: Arrow a => a b c -> a b c' -> a b (c, c') infixr 3 &&& -- | Identity functor and monad. (a non-strict monad) newtype Identity a Identity :: a -> Identity a [runIdentity] :: Identity a -> a -- | A handle managing output to the Haskell program's standard error -- channel. stderr :: Handle -- | A handle managing input from the Haskell program's standard input -- channel. stdin :: Handle -- | Perform some computation without adding new entries to the -- CallStack. withFrozenCallStack :: HasCallStack => (HasCallStack => a) -> a -- | Return the current CallStack. -- -- Does *not* include the call-site of callStack. callStack :: HasCallStack => CallStack -- | Write the supplied value into a TVar. writeTVar :: TVar a -> a -> STM () -- | Return the current value stored in a TVar. readTVar :: TVar a -> STM a -- | Create a new TVar holding a value supplied newTVar :: a -> STM (TVar a) -- | A monad supporting atomic memory transactions. data STM a -- | Shared memory locations that support atomic memory transactions. data TVar a -- | A mutable variable in the IO monad data IORef a -- | File and directory names are values of type String, whose -- precise meaning is operating system dependent. Files can be opened, -- yielding a handle which can then be used to operate on the contents of -- that file. type FilePath = String -- | Pretty print a CallStack. prettyCallStack :: CallStack -> String -- | Pretty print a SrcLoc. prettySrcLoc :: SrcLoc -> String -- | Any type that you wish to throw or catch as an exception must be an -- instance of the Exception class. The simplest case is a new -- exception type directly below the root: -- --
-- data MyException = ThisException | ThatException -- deriving Show -- -- instance Exception MyException ---- -- The default method definitions in the Exception class do what -- we need in this case. You can now throw and catch -- ThisException and ThatException as exceptions: -- --
-- *Main> throw ThisException `catch` \e -> putStrLn ("Caught " ++ show (e :: MyException))
-- Caught ThisException
--
--
-- In more complicated examples, you may wish to define a whole hierarchy
-- of exceptions:
--
-- -- --------------------------------------------------------------------- -- -- Make the root exception type for all the exceptions in a compiler -- -- data SomeCompilerException = forall e . Exception e => SomeCompilerException e -- -- instance Show SomeCompilerException where -- show (SomeCompilerException e) = show e -- -- instance Exception SomeCompilerException -- -- compilerExceptionToException :: Exception e => e -> SomeException -- compilerExceptionToException = toException . SomeCompilerException -- -- compilerExceptionFromException :: Exception e => SomeException -> Maybe e -- compilerExceptionFromException x = do -- SomeCompilerException a <- fromException x -- cast a -- -- --------------------------------------------------------------------- -- -- Make a subhierarchy for exceptions in the frontend of the compiler -- -- data SomeFrontendException = forall e . Exception e => SomeFrontendException e -- -- instance Show SomeFrontendException where -- show (SomeFrontendException e) = show e -- -- instance Exception SomeFrontendException where -- toException = compilerExceptionToException -- fromException = compilerExceptionFromException -- -- frontendExceptionToException :: Exception e => e -> SomeException -- frontendExceptionToException = toException . SomeFrontendException -- -- frontendExceptionFromException :: Exception e => SomeException -> Maybe e -- frontendExceptionFromException x = do -- SomeFrontendException a <- fromException x -- cast a -- -- --------------------------------------------------------------------- -- -- Make an exception type for a particular frontend compiler exception -- -- data MismatchedParentheses = MismatchedParentheses -- deriving Show -- -- instance Exception MismatchedParentheses where -- toException = frontendExceptionToException -- fromException = frontendExceptionFromException ---- -- We can now catch a MismatchedParentheses exception as -- MismatchedParentheses, SomeFrontendException or -- SomeCompilerException, but not other types, e.g. -- IOException: -- --
-- *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: MismatchedParentheses))
-- Caught MismatchedParentheses
-- *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: SomeFrontendException))
-- Caught MismatchedParentheses
-- *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: SomeCompilerException))
-- Caught MismatchedParentheses
-- *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: IOException))
-- *** Exception: MismatchedParentheses
--
class (Typeable e, Show e) => Exception e
toException :: Exception e => e -> SomeException
fromException :: Exception e => SomeException -> Maybe e
-- | Render this exception value in a human-friendly manner.
--
-- Default implementation: show.
displayException :: Exception e => e -> String
-- | The Const functor.
newtype Const a (b :: k)
Const :: a -> Const a (b :: k)
[getConst] :: Const a (b :: k) -> a
-- | The least element of a non-empty structure with respect to the given
-- comparison function.
minimumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a
-- | The largest element of a non-empty structure with respect to the given
-- comparison function.
maximumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a
-- | Map a function over all the elements of a container and concatenate
-- the resulting lists.
concatMap :: Foldable t => (a -> [b]) -> t a -> [b]
-- | The concatenation of all the elements of a container of lists.
concat :: Foldable t => t [a] -> [a]
-- | Monadic fold over the elements of a structure, associating to the
-- left, i.e. from left to right.
foldlM :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b
-- | Monadic fold over the elements of a structure, associating to the
-- right, i.e. from right to left.
foldrM :: (Foldable t, Monad m) => (a -> b -> m b) -> b -> t a -> m b
-- | Maybe monoid returning the leftmost non-Nothing value.
--
-- First a is isomorphic to Alt Maybe
-- a, but precedes it historically.
--
-- -- >>> getFirst (First (Just "hello") <> First Nothing <> First (Just "world")) -- Just "hello" ---- -- Use of this type is discouraged. Note the following equivalence: -- --
-- Data.Monoid.First x === Maybe (Data.Semigroup.First x) ---- -- In addition to being equivalent in the structural sense, the two also -- have Monoid instances that behave the same. This type will be -- marked deprecated in GHC 8.8, and removed in GHC 8.10. Users are -- advised to use the variant from Data.Semigroup and wrap it in -- Maybe. newtype First a First :: Maybe a -> First a [getFirst] :: First a -> Maybe a -- | Maybe monoid returning the rightmost non-Nothing value. -- -- Last a is isomorphic to Dual (First -- a), and thus to Dual (Alt Maybe a) -- --
-- >>> getLast (Last (Just "hello") <> Last Nothing <> Last (Just "world")) -- Just "world" ---- -- Use of this type is discouraged. Note the following equivalence: -- --
-- Data.Monoid.Last x === Maybe (Data.Semigroup.Last x) ---- -- In addition to being equivalent in the structural sense, the two also -- have Monoid instances that behave the same. This type will be -- marked deprecated in GHC 8.8, and removed in GHC 8.10. Users are -- advised to use the variant from Data.Semigroup and wrap it in -- Maybe. newtype Last a Last :: Maybe a -> Last a [getLast] :: Last a -> Maybe a -- | This is a valid definition of stimes for a Monoid. -- -- Unlike the default definition of stimes, it is defined for 0 -- and so it should be preferred where possible. stimesMonoid :: (Integral b, Monoid a) => b -> a -> a -- | This is a valid definition of stimes for an idempotent -- Semigroup. -- -- When x <> x = x, this definition should be preferred, -- because it works in O(1) rather than O(log n). stimesIdempotent :: Integral b => b -> a -> a -- | The dual of a Monoid, obtained by swapping the arguments of -- mappend. -- --
-- >>> getDual (mappend (Dual "Hello") (Dual "World")) -- "WorldHello" --newtype Dual a Dual :: a -> Dual a [getDual] :: Dual a -> a -- | The monoid of endomorphisms under composition. -- --
-- >>> let computation = Endo ("Hello, " ++) <> Endo (++ "!")
--
-- >>> appEndo computation "Haskell"
-- "Hello, Haskell!"
--
newtype Endo a
Endo :: (a -> a) -> Endo a
[appEndo] :: Endo a -> a -> a
-- | Boolean monoid under conjunction (&&).
--
-- -- >>> getAll (All True <> mempty <> All False) -- False ---- --
-- >>> getAll (mconcat (map (\x -> All (even x)) [2,4,6,7,8])) -- False --newtype All All :: Bool -> All [getAll] :: All -> Bool -- | Boolean monoid under disjunction (||). -- --
-- >>> getAny (Any True <> mempty <> Any False) -- True ---- --
-- >>> getAny (mconcat (map (\x -> Any (even x)) [2,4,6,7,8])) -- True --newtype Any Any :: Bool -> Any [getAny] :: Any -> Bool -- | Monoid under addition. -- --
-- >>> getSum (Sum 1 <> Sum 2 <> mempty) -- 3 --newtype Sum a Sum :: a -> Sum a [getSum] :: Sum a -> a -- | Monoid under multiplication. -- --
-- >>> getProduct (Product 3 <> Product 4 <> mempty) -- 12 --newtype Product a Product :: a -> Product a [getProduct] :: Product a -> a -- | Monoid under <|>. newtype Alt (f :: k -> Type) (a :: k) Alt :: f a -> Alt (f :: k -> Type) (a :: k) [getAlt] :: Alt (f :: k -> Type) (a :: k) -> f a -- | Convert an integer into an unknown type-level natural. someNatVal :: Natural -> SomeNat natVal :: forall (n :: Nat) proxy. KnownNat n => proxy n -> Natural -- | This type represents unknown type-level natural numbers. data SomeNat SomeNat :: Proxy n -> SomeNat -- | The unfoldr function is a `dual' to foldr: while -- foldr reduces a list to a summary value, unfoldr builds -- a list from a seed value. The function takes the element and returns -- Nothing if it is done producing the list or returns Just -- (a,b), in which case, a is a prepended to the list -- and b is used as the next element in a recursive call. For -- example, -- --
-- iterate f == unfoldr (\x -> Just (x, f x)) ---- -- In some cases, unfoldr can undo a foldr operation: -- --
-- unfoldr f' (foldr f z xs) == xs ---- -- if the following holds: -- --
-- f' (f x y) = Just (x,y) -- f' z = Nothing ---- -- A simple use of unfoldr: -- --
-- >>> unfoldr (\b -> if b == 0 then Nothing else Just (b, b-1)) 10 -- [10,9,8,7,6,5,4,3,2,1] --unfoldr :: (b -> Maybe (a, b)) -> b -> [a] -- | Sort a list by comparing the results of a key function applied to each -- element. sortOn f is equivalent to sortBy (comparing -- f), but has the performance advantage of only evaluating -- f once for each element in the input list. This is called the -- decorate-sort-undecorate paradigm, or Schwartzian transform. -- -- Elements are arranged from from lowest to highest, keeping duplicates -- in the order they appeared in the input. -- --
-- >>> sortOn fst [(2, "world"), (4, "!"), (1, "Hello")] -- [(1,"Hello"),(2,"world"),(4,"!")] --sortOn :: Ord b => (a -> b) -> [a] -> [a] -- | The sortBy function is the non-overloaded version of -- sort. -- --
-- >>> sortBy (\(a,_) (b,_) -> compare a b) [(2, "world"), (4, "!"), (1, "Hello")] -- [(1,"Hello"),(2,"world"),(4,"!")] --sortBy :: (a -> a -> Ordering) -> [a] -> [a] -- | The sort function implements a stable sorting algorithm. It is -- a special case of sortBy, which allows the programmer to supply -- their own comparison function. -- -- Elements are arranged from from lowest to highest, keeping duplicates -- in the order they appeared in the input. -- --
-- >>> sort [1,6,4,3,2,5] -- [1,2,3,4,5,6] --sort :: Ord a => [a] -> [a] -- | The permutations function returns the list of all permutations -- of the argument. -- --
-- >>> permutations "abc" -- ["abc","bac","cba","bca","cab","acb"] --permutations :: [a] -> [[a]] -- | The subsequences function returns the list of all subsequences -- of the argument. -- --
-- >>> subsequences "abc" -- ["","a","b","ab","c","ac","bc","abc"] --subsequences :: [a] -> [[a]] -- | O(n). The tails function returns all final segments of -- the argument, longest first. For example, -- --
-- >>> tails "abc" -- ["abc","bc","c",""] ---- -- Note that tails has the following strictness property: -- tails _|_ = _|_ : _|_ tails :: [a] -> [[a]] -- | The inits function returns all initial segments of the -- argument, shortest first. For example, -- --
-- >>> inits "abc" -- ["","a","ab","abc"] ---- -- Note that inits has the following strictness property: -- inits (xs ++ _|_) = inits xs ++ _|_ -- -- In particular, inits _|_ = [] : _|_ inits :: [a] -> [[a]] -- | The group function takes a list and returns a list of lists -- such that the concatenation of the result is equal to the argument. -- Moreover, each sublist in the result contains only equal elements. For -- example, -- --
-- >>> group "Mississippi" -- ["M","i","ss","i","ss","i","pp","i"] ---- -- It is a special case of groupBy, which allows the programmer to -- supply their own equality test. group :: Eq a => [a] -> [[a]] -- | The genericReplicate function is an overloaded version of -- replicate, which accepts any Integral value as the -- number of repetitions to make. genericReplicate :: Integral i => i -> a -> [a] -- | The genericSplitAt function is an overloaded version of -- splitAt, which accepts any Integral value as the -- position at which to split. genericSplitAt :: Integral i => i -> [a] -> ([a], [a]) -- | The genericDrop function is an overloaded version of -- drop, which accepts any Integral value as the number of -- elements to drop. genericDrop :: Integral i => i -> [a] -> [a] -- | The genericTake function is an overloaded version of -- take, which accepts any Integral value as the number of -- elements to take. genericTake :: Integral i => i -> [a] -> [a] -- | O(n). The genericLength function is an overloaded -- version of length. In particular, instead of returning an -- Int, it returns any type which is an instance of Num. It -- is, however, less efficient than length. -- --
-- >>> genericLength [1, 2, 3] :: Int -- 3 -- -- >>> genericLength [1, 2, 3] :: Float -- 3.0 --genericLength :: Num i => [a] -> i -- | The transpose function transposes the rows and columns of its -- argument. For example, -- --
-- >>> transpose [[1,2,3],[4,5,6]] -- [[1,4],[2,5],[3,6]] ---- -- If some of the rows are shorter than the following rows, their -- elements are skipped: -- --
-- >>> transpose [[10,11],[20],[],[30,31,32]] -- [[10,20,30],[11,31],[32]] --transpose :: [[a]] -> [[a]] -- | intercalate xs xss is equivalent to (concat -- (intersperse xs xss)). It inserts the list xs in -- between the lists in xss and concatenates the result. -- --
-- >>> intercalate ", " ["Lorem", "ipsum", "dolor"] -- "Lorem, ipsum, dolor" --intercalate :: [a] -> [[a]] -> [a] -- | O(n). The intersperse function takes an element and a -- list and `intersperses' that element between the elements of the list. -- For example, -- --
-- >>> intersperse ',' "abcde" -- "a,b,c,d,e" --intersperse :: a -> [a] -> [a] -- | O(min(m,n)). The isPrefixOf function takes two lists and -- returns True iff the first list is a prefix of the second. -- --
-- >>> "Hello" `isPrefixOf` "Hello World!" -- True ---- --
-- >>> "Hello" `isPrefixOf` "Wello Horld!" -- False --isPrefixOf :: Eq a => [a] -> [a] -> Bool -- | Parse a string using the Read instance. Succeeds if there is -- exactly one valid result. -- --
-- >>> readMaybe "123" :: Maybe Int -- Just 123 ---- --
-- >>> readMaybe "hello" :: Maybe Int -- Nothing --readMaybe :: Read a => String -> Maybe a -- | equivalent to readsPrec with a precedence of 0. reads :: Read a => ReadS a -- | Return True if the given value is a Right-value, -- False otherwise. -- --
-- >>> isRight (Left "foo") -- False -- -- >>> isRight (Right 3) -- True ---- -- Assuming a Left value signifies some sort of error, we can use -- isRight to write a very simple reporting function that only -- outputs "SUCCESS" when a computation has succeeded. -- -- This example shows how isRight might be used to avoid pattern -- matching when one does not care about the value contained in the -- constructor: -- --
-- >>> import Control.Monad ( when ) -- -- >>> let report e = when (isRight e) $ putStrLn "SUCCESS" -- -- >>> report (Left "parse error") -- -- >>> report (Right 1) -- SUCCESS --isRight :: Either a b -> Bool -- | Return True if the given value is a Left-value, -- False otherwise. -- --
-- >>> isLeft (Left "foo") -- True -- -- >>> isLeft (Right 3) -- False ---- -- Assuming a Left value signifies some sort of error, we can use -- isLeft to write a very simple error-reporting function that -- does absolutely nothing in the case of success, and outputs "ERROR" if -- any error occurred. -- -- This example shows how isLeft might be used to avoid pattern -- matching when one does not care about the value contained in the -- constructor: -- --
-- >>> import Control.Monad ( when ) -- -- >>> let report e = when (isLeft e) $ putStrLn "ERROR" -- -- >>> report (Right 1) -- -- >>> report (Left "parse error") -- ERROR --isLeft :: Either a b -> Bool -- | Partitions a list of Either into two lists. All the Left -- elements are extracted, in order, to the first component of the -- output. Similarly the Right elements are extracted to the -- second component of the output. -- --
-- >>> let list = [ Left "foo", Right 3, Left "bar", Right 7, Left "baz" ] -- -- >>> partitionEithers list -- (["foo","bar","baz"],[3,7]) ---- -- The pair returned by partitionEithers x should be the -- same pair as (lefts x, rights x): -- --
-- >>> let list = [ Left "foo", Right 3, Left "bar", Right 7, Left "baz" ] -- -- >>> partitionEithers list == (lefts list, rights list) -- True --partitionEithers :: [Either a b] -> ([a], [b]) -- | Extracts from a list of Either all the Right elements. -- All the Right elements are extracted in order. -- --
-- >>> let list = [ Left "foo", Right 3, Left "bar", Right 7, Left "baz" ] -- -- >>> rights list -- [3,7] --rights :: [Either a b] -> [b] -- | Extracts from a list of Either all the Left elements. -- All the Left elements are extracted in order. -- --
-- >>> let list = [ Left "foo", Right 3, Left "bar", Right 7, Left "baz" ] -- -- >>> lefts list -- ["foo","bar","baz"] --lefts :: [Either a b] -> [a] -- |
-- comparing p x y = compare (p x) (p y) ---- -- Useful combinator for use in conjunction with the xxxBy -- family of functions from Data.List, for example: -- --
-- ... sortBy (comparing fst) ... --comparing :: Ord a => (b -> a) -> b -> b -> Ordering -- | The Down type allows you to reverse sort order conveniently. A -- value of type Down a contains a value of type -- a (represented as Down a). If a has -- an Ord instance associated with it then comparing two -- values thus wrapped will give you the opposite of their normal sort -- order. This is particularly useful when sorting in generalised list -- comprehensions, as in: then sortWith by Down x newtype Down a Down :: a -> Down a -- | Proxy is a type that holds no data, but has a phantom parameter -- of arbitrary type (or even kind). Its use is to provide type -- information, even though there is no value available of that type (or -- it may be too costly to create one). -- -- Historically, Proxy :: Proxy a is a safer -- alternative to the undefined :: a idiom. -- --
-- >>> Proxy :: Proxy (Void, Int -> Int) -- Proxy ---- -- Proxy can even hold types of higher kinds, -- --
-- >>> Proxy :: Proxy Either -- Proxy ---- --
-- >>> Proxy :: Proxy Functor -- Proxy ---- --
-- >>> Proxy :: Proxy complicatedStructure -- Proxy --data Proxy (t :: k) Proxy :: Proxy (t :: k) -- | See openFile data IOMode ReadMode :: IOMode WriteMode :: IOMode AppendMode :: IOMode ReadWriteMode :: IOMode -- | Reverse order of bytes in Word64. byteSwap64 :: Word64 -> Word64 -- | Reverse order of bytes in Word32. byteSwap32 :: Word32 -> Word32 -- | Swap bytes in Word16. byteSwap16 :: Word16 -> Word16 -- | Bitwise "xor" xor :: Bits a => a -> a -> a infixl 6 `xor` integralEnumFromThenTo :: Integral a => a -> a -> a -> [a] integralEnumFromTo :: Integral a => a -> a -> [a] integralEnumFromThen :: (Integral a, Bounded a) => a -> a -> [a] integralEnumFrom :: (Integral a, Bounded a) => a -> [a] gcdWord' :: Word -> Word -> Word gcdInt' :: Int -> Int -> Int -- | lcm x y is the smallest positive integer that both -- x and y divide. lcm :: Integral a => a -> a -> a -- | gcd x y is the non-negative factor of both x -- and y of which every common factor of x and -- y is also a factor; for example gcd 4 2 = 2, -- gcd (-4) 6 = 2, gcd 0 4 = 4. -- gcd 0 0 = 0. (That is, the common divisor -- that is "greatest" in the divisibility preordering.) -- -- Note: Since for signed fixed-width integer types, abs -- minBound < 0, the result may be negative if one of the -- arguments is minBound (and necessarily is if the other -- is 0 or minBound) for such types. gcd :: Integral a => a -> a -> a (^^%^^) :: Integral a => Rational -> a -> Rational (^%^) :: Integral a => Rational -> a -> Rational -- | raise a number to an integral power (^^) :: (Fractional a, Integral b) => a -> b -> a infixr 8 ^^ -- | raise a number to a non-negative integral power (^) :: (Num a, Integral b) => a -> b -> a infixr 8 ^ odd :: Integral a => a -> Bool even :: Integral a => a -> Bool numericEnumFromThenTo :: (Ord a, Fractional a) => a -> a -> a -> [a] numericEnumFromTo :: (Ord a, Fractional a) => a -> a -> [a] numericEnumFromThen :: Fractional a => a -> a -> [a] numericEnumFrom :: Fractional a => a -> [a] -- | Extract the denominator of the ratio in reduced form: the numerator -- and denominator have no common factor and the denominator is positive. denominator :: Ratio a -> a -- | Extract the numerator of the ratio in reduced form: the numerator and -- denominator have no common factor and the denominator is positive. numerator :: Ratio a -> a -- | reduce is a subsidiary function used only in this module. It -- normalises a ratio by dividing both numerator and denominator by their -- greatest common divisor. reduce :: Integral a => a -> a -> Ratio a notANumber :: Rational infinity :: Rational ratioPrec1 :: Int ratioPrec :: Int underflowError :: a overflowError :: a ratioZeroDenominatorError :: a divZeroError :: a boundedEnumFromThen :: (Enum a, Bounded a) => a -> a -> [a] boundedEnumFrom :: (Enum a, Bounded a) => a -> [a] -- | The toEnum method restricted to the type Char. chr :: Int -> Char -- | The unzip3 function takes a list of triples and returns three -- lists, analogous to unzip. unzip3 :: [(a, b, c)] -> ([a], [b], [c]) -- | unzip transforms a list of pairs into a list of first -- components and a list of second components. unzip :: [(a, b)] -> ([a], [b]) -- | O(min(m,n)). zipWith generalises zip by zipping -- with the function given as the first argument, instead of a tupling -- function. For example, zipWith (+) is applied to two -- lists to produce the list of corresponding sums: -- --
-- >>> zipWith (+) [1, 2, 3] [4, 5, 6] -- [5,7,9] ---- -- zipWith is right-lazy: -- --
-- zipWith f [] _|_ = [] ---- -- zipWith is capable of list fusion, but it is restricted to its -- first list argument and its resulting list. zipWith :: (a -> b -> c) -> [a] -> [b] -> [c] -- | zip3 takes three lists and returns a list of triples, analogous -- to zip. It is capable of list fusion, but it is restricted to -- its first list argument and its resulting list. zip3 :: [a] -> [b] -> [c] -> [(a, b, c)] -- | reverse xs returns the elements of xs in -- reverse order. xs must be finite. reverse :: [a] -> [a] -- | break, applied to a predicate p and a list -- xs, returns a tuple where first element is longest prefix -- (possibly empty) of xs of elements that do not satisfy -- p and second element is the remainder of the list: -- --
-- break (> 3) [1,2,3,4,1,2,3,4] == ([1,2,3],[4,1,2,3,4]) -- break (< 9) [1,2,3] == ([],[1,2,3]) -- break (> 9) [1,2,3] == ([1,2,3],[]) ---- -- break p is equivalent to span (not . -- p). break :: (a -> Bool) -> [a] -> ([a], [a]) -- | splitAt n xs returns a tuple where first element is -- xs prefix of length n and second element is the -- remainder of the list: -- --
-- splitAt 6 "Hello World!" == ("Hello ","World!")
-- splitAt 3 [1,2,3,4,5] == ([1,2,3],[4,5])
-- splitAt 1 [1,2,3] == ([1],[2,3])
-- splitAt 3 [1,2,3] == ([1,2,3],[])
-- splitAt 4 [1,2,3] == ([1,2,3],[])
-- splitAt 0 [1,2,3] == ([],[1,2,3])
-- splitAt (-1) [1,2,3] == ([],[1,2,3])
--
--
-- It is equivalent to (take n xs, drop n xs) when
-- n is not _|_ (splitAt _|_ xs = _|_).
-- splitAt is an instance of the more general
-- genericSplitAt, in which n may be of any integral
-- type.
splitAt :: Int -> [a] -> ([a], [a])
-- | drop n xs returns the suffix of xs after the
-- first n elements, or [] if n > length
-- xs:
--
-- -- drop 6 "Hello World!" == "World!" -- drop 3 [1,2,3,4,5] == [4,5] -- drop 3 [1,2] == [] -- drop 3 [] == [] -- drop (-1) [1,2] == [1,2] -- drop 0 [1,2] == [1,2] ---- -- It is an instance of the more general genericDrop, in which -- n may be of any integral type. drop :: Int -> [a] -> [a] -- | take n, applied to a list xs, returns the -- prefix of xs of length n, or xs itself if -- n > length xs: -- --
-- take 5 "Hello World!" == "Hello" -- take 3 [1,2,3,4,5] == [1,2,3] -- take 3 [1,2] == [1,2] -- take 3 [] == [] -- take (-1) [1,2] == [] -- take 0 [1,2] == [] ---- -- It is an instance of the more general genericTake, in which -- n may be of any integral type. take :: Int -> [a] -> [a] -- | dropWhile p xs returns the suffix remaining after -- takeWhile p xs: -- --
-- dropWhile (< 3) [1,2,3,4,5,1,2,3] == [3,4,5,1,2,3] -- dropWhile (< 9) [1,2,3] == [] -- dropWhile (< 0) [1,2,3] == [1,2,3] --dropWhile :: (a -> Bool) -> [a] -> [a] -- | takeWhile, applied to a predicate p and a list -- xs, returns the longest prefix (possibly empty) of -- xs of elements that satisfy p: -- --
-- takeWhile (< 3) [1,2,3,4,1,2,3,4] == [1,2] -- takeWhile (< 9) [1,2,3] == [1,2,3] -- takeWhile (< 0) [1,2,3] == [] --takeWhile :: (a -> Bool) -> [a] -> [a] -- | cycle ties a finite list into a circular one, or equivalently, -- the infinite repetition of the original list. It is the identity on -- infinite lists. cycle :: [a] -> [a] -- | replicate n x is a list of length n with -- x the value of every element. It is an instance of the more -- general genericReplicate, in which n may be of any -- integral type. replicate :: Int -> a -> [a] -- | repeat x is an infinite list, with x the -- value of every element. repeat :: a -> [a] -- | iterate f x returns an infinite list of repeated -- applications of f to x: -- --
-- iterate f x == [x, f x, f (f x), ...] ---- -- Note that iterate is lazy, potentially leading to thunk -- build-up if the consumer doesn't force each iterate. See -- iterate' for a strict variant of this function. iterate :: (a -> a) -> a -> [a] -- | O(n). scanr is the right-to-left dual of scanl. -- Note that -- --
-- head (scanr f z xs) == foldr f z xs. --scanr :: (a -> b -> b) -> b -> [a] -> [b] -- | O(n). scanl is similar to foldl, but returns a -- list of successive reduced values from the left: -- --
-- scanl f z [x1, x2, ...] == [z, z `f` x1, (z `f` x1) `f` x2, ...] ---- -- Note that -- --
-- last (scanl f z xs) == foldl f z xs. --scanl :: (b -> a -> b) -> b -> [a] -> [b] -- | The mapMaybe function is a version of map which can -- throw out elements. In particular, the functional argument returns -- something of type Maybe b. If this is Nothing, -- no element is added on to the result list. If it is Just -- b, then b is included in the result list. -- --
-- >>> import Text.Read ( readMaybe ) -- -- >>> let readMaybeInt = readMaybe :: String -> Maybe Int -- -- >>> mapMaybe readMaybeInt ["1", "Foo", "3"] -- [1,3] -- -- >>> catMaybes $ map readMaybeInt ["1", "Foo", "3"] -- [1,3] ---- -- If we map the Just constructor, the entire list should be -- returned: -- --
-- >>> mapMaybe Just [1,2,3] -- [1,2,3] --mapMaybe :: (a -> Maybe b) -> [a] -> [b] -- | The catMaybes function takes a list of Maybes and -- returns a list of all the Just values. -- --
-- >>> catMaybes [Just 1, Nothing, Just 3] -- [1,3] ---- -- When constructing a list of Maybe values, catMaybes can -- be used to return all of the "success" results (if the list is the -- result of a map, then mapMaybe would be more -- appropriate): -- --
-- >>> import Text.Read ( readMaybe ) -- -- >>> [readMaybe x :: Maybe Int | x <- ["1", "Foo", "3"] ] -- [Just 1,Nothing,Just 3] -- -- >>> catMaybes $ [readMaybe x :: Maybe Int | x <- ["1", "Foo", "3"] ] -- [1,3] --catMaybes :: [Maybe a] -> [a] -- | The listToMaybe function returns Nothing on an empty -- list or Just a where a is the first element -- of the list. -- --
-- >>> listToMaybe [] -- Nothing ---- --
-- >>> listToMaybe [9] -- Just 9 ---- --
-- >>> listToMaybe [1,2,3] -- Just 1 ---- -- Composing maybeToList with listToMaybe should be the -- identity on singleton/empty lists: -- --
-- >>> maybeToList $ listToMaybe [5] -- [5] -- -- >>> maybeToList $ listToMaybe [] -- [] ---- -- But not on lists with more than one element: -- --
-- >>> maybeToList $ listToMaybe [1,2,3] -- [1] --listToMaybe :: [a] -> Maybe a -- | The maybeToList function returns an empty list when given -- Nothing or a singleton list when given Just. -- --
-- >>> maybeToList (Just 7) -- [7] ---- --
-- >>> maybeToList Nothing -- [] ---- -- One can use maybeToList to avoid pattern matching when combined -- with a function that (safely) works on lists: -- --
-- >>> import Text.Read ( readMaybe ) -- -- >>> sum $ maybeToList (readMaybe "3") -- 3 -- -- >>> sum $ maybeToList (readMaybe "") -- 0 --maybeToList :: Maybe a -> [a] -- | The fromMaybe function takes a default value and and -- Maybe value. If the Maybe is Nothing, it returns -- the default values; otherwise, it returns the value contained in the -- Maybe. -- --
-- >>> fromMaybe "" (Just "Hello, World!") -- "Hello, World!" ---- --
-- >>> fromMaybe "" Nothing -- "" ---- -- Read an integer from a string using readMaybe. If we fail to -- parse an integer, we want to return 0 by default: -- --
-- >>> import Text.Read ( readMaybe ) -- -- >>> fromMaybe 0 (readMaybe "5") -- 5 -- -- >>> fromMaybe 0 (readMaybe "") -- 0 --fromMaybe :: a -> Maybe a -> a -- | The isNothing function returns True iff its argument is -- Nothing. -- --
-- >>> isNothing (Just 3) -- False ---- --
-- >>> isNothing (Just ()) -- False ---- --
-- >>> isNothing Nothing -- True ---- -- Only the outer constructor is taken into consideration: -- --
-- >>> isNothing (Just Nothing) -- False --isNothing :: Maybe a -> Bool -- | The isJust function returns True iff its argument is of -- the form Just _. -- --
-- >>> isJust (Just 3) -- True ---- --
-- >>> isJust (Just ()) -- True ---- --
-- >>> isJust Nothing -- False ---- -- Only the outer constructor is taken into consideration: -- --
-- >>> isJust (Just Nothing) -- True --isJust :: Maybe a -> Bool -- | The maybe function takes a default value, a function, and a -- Maybe value. If the Maybe value is Nothing, the -- function returns the default value. Otherwise, it applies the function -- to the value inside the Just and returns the result. -- --
-- >>> maybe False odd (Just 3) -- True ---- --
-- >>> maybe False odd Nothing -- False ---- -- Read an integer from a string using readMaybe. If we succeed, -- return twice the integer; that is, apply (*2) to it. If -- instead we fail to parse an integer, return 0 by default: -- --
-- >>> import Text.Read ( readMaybe ) -- -- >>> maybe 0 (*2) (readMaybe "5") -- 10 -- -- >>> maybe 0 (*2) (readMaybe "") -- 0 ---- -- Apply show to a Maybe Int. If we have Just n, -- we want to show the underlying Int n. But if we have -- Nothing, we return the empty string instead of (for example) -- "Nothing": -- --
-- >>> maybe "" show (Just 5) -- "5" -- -- >>> maybe "" show Nothing -- "" --maybe :: b -> (a -> b) -> Maybe a -> b -- | Case analysis for the Bool type. bool x y p -- evaluates to x when p is False, and evaluates -- to y when p is True. -- -- This is equivalent to if p then y else x; that is, one can -- think of it as an if-then-else construct with its arguments reordered. -- --
-- >>> bool "foo" "bar" True -- "bar" -- -- >>> bool "foo" "bar" False -- "foo" ---- -- Confirm that bool x y p and if p then y else -- x are equivalent: -- --
-- >>> let p = True; x = "bar"; y = "foo" -- -- >>> bool x y p == if p then y else x -- True -- -- >>> let p = False -- -- >>> bool x y p == if p then y else x -- True --bool :: a -> a -> Bool -> a -- | & is a reverse application operator. This provides -- notational convenience. Its precedence is one higher than that of the -- forward application operator $, which allows & to be -- nested in $. -- --
-- >>> 5 & (+1) & show -- "6" --(&) :: a -> (a -> b) -> b infixl 1 & -- | on b u x y runs the binary function b -- on the results of applying unary function u to two -- arguments x and y. From the opposite perspective, it -- transforms two inputs and combines the outputs. -- --
-- ((+) `on` f) x y = f x + f y ---- -- Typical usage: sortBy (compare `on` -- fst). -- -- Algebraic properties: -- --
(*) `on` id = (*) -- (if (*) ∉ {⊥, const -- ⊥})
((*) `on` f) `on` g = (*) `on` (f . g)
flip on f . flip on g = flip on (g . -- f)
-- >>> let fac n = if n <= 1 then 1 else n * fac (n-1) in fac 5 -- 120 ---- -- This uses the fact that Haskell’s let introduces recursive -- bindings. We can rewrite this definition using fix, -- --
-- >>> fix (\rec n -> if n <= 1 then 1 else n * rec (n-1)) 5 -- 120 ---- -- Instead of making a recursive call, we introduce a dummy parameter -- rec; when used within fix, this parameter then refers -- to fix argument, hence the recursion is reintroduced. fix :: (a -> a) -> a -- | void value discards or ignores the result of -- evaluation, such as the return value of an IO action. -- --
-- >>> void Nothing -- Nothing -- -- >>> void (Just 3) -- Just () ---- -- Replace the contents of an Either Int -- Int with unit, resulting in an Either -- Int (): -- --
-- >>> void (Left 8675309) -- Left 8675309 -- -- >>> void (Right 8675309) -- Right () ---- -- Replace every element of a list with unit: -- --
-- >>> void [1,2,3] -- [(),(),()] ---- -- Replace the second element of a pair with unit: -- --
-- >>> void (1,2) -- (1,()) ---- -- Discard the result of an IO action: -- --
-- >>> mapM print [1,2] -- 1 -- 2 -- [(),()] -- -- >>> void $ mapM print [1,2] -- 1 -- 2 --void :: Functor f => f a -> f () -- | Flipped version of <$. -- --
-- >>> Nothing $> "foo" -- Nothing -- -- >>> Just 90210 $> "foo" -- Just "foo" ---- -- Replace the contents of an Either Int -- Int with a constant String, resulting in an -- Either Int String: -- --
-- >>> Left 8675309 $> "foo" -- Left 8675309 -- -- >>> Right 8675309 $> "foo" -- Right "foo" ---- -- Replace each element of a list with a constant String: -- --
-- >>> [1,2,3] $> "foo" -- ["foo","foo","foo"] ---- -- Replace the second element of a pair with a constant String: -- --
-- >>> (1,2) $> "foo" -- (1,"foo") --($>) :: Functor f => f a -> b -> f b infixl 4 $> -- | Flipped version of <$>. -- --
-- (<&>) = flip fmap ---- --
-- >>> Just 2 <&> (+1) -- Just 3 ---- --
-- >>> [1,2,3] <&> (+1) -- [2,3,4] ---- --
-- >>> Right 3 <&> (+1) -- Right 4 --(<&>) :: Functor f => f a -> (a -> b) -> f b infixl 1 <&> -- | Swap the components of a pair. swap :: (a, b) -> (b, a) -- | uncurry converts a curried function to a function on pairs. -- --
-- >>> uncurry (+) (1,2) -- 3 ---- --
-- >>> uncurry ($) (show, 1) -- "1" ---- --
-- >>> map (uncurry max) [(1,2), (3,4), (6,8)] -- [2,4,8] --uncurry :: (a -> b -> c) -> (a, b) -> c -- | curry converts an uncurried function to a curried function. -- --
-- >>> curry fst 1 2 -- 1 --curry :: ((a, b) -> c) -> a -> b -> c -- | An MVar (pronounced "em-var") is a synchronising variable, used -- for communication between concurrent threads. It can be thought of as -- a box, which may be empty or full. data MVar a -- | the same as flip (-). -- -- Because - is treated specially in the Haskell grammar, -- (- e) is not a section, but an application of -- prefix negation. However, (subtract -- exp) is equivalent to the disallowed section. subtract :: Num a => a -> a -> a -- | Returns a [String] representing the current call stack. This -- can be useful for debugging. -- -- The implementation uses the call-stack simulation maintained by the -- profiler, so it only works if the program was compiled with -- -prof and contains suitable SCC annotations (e.g. by using -- -fprof-auto). Otherwise, the list returned is likely to be -- empty or uninformative. currentCallStack :: IO [String] -- | asTypeOf is a type-restricted version of const. It is -- usually used as an infix operator, and its typing forces its first -- argument (which is usually overloaded) to have the same type as the -- second. asTypeOf :: a -> a -> a -- | flip f takes its (first) two arguments in the reverse -- order of f. -- --
-- >>> flip (++) "hello" "world" -- "worldhello" --flip :: (a -> b -> c) -> b -> a -> c maxInt :: Int minInt :: Int -- | The fromEnum method restricted to the type Char. ord :: Char -> Int -- | In many situations, the liftM operations can be replaced by -- uses of ap, which promotes function application. -- --
-- return f `ap` x1 `ap` ... `ap` xn ---- -- is equivalent to -- --
-- liftMn f x1 x2 ... xn --ap :: Monad m => m (a -> b) -> m a -> m b -- | Promote a function to a monad, scanning the monadic arguments from -- left to right (cf. liftM2). liftM5 :: Monad m => (a1 -> a2 -> a3 -> a4 -> a5 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m a5 -> m r -- | Promote a function to a monad, scanning the monadic arguments from -- left to right (cf. liftM2). liftM4 :: Monad m => (a1 -> a2 -> a3 -> a4 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m r -- | Promote a function to a monad, scanning the monadic arguments from -- left to right (cf. liftM2). liftM3 :: Monad m => (a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r -- | Promote a function to a monad, scanning the monadic arguments from -- left to right. For example, -- --
-- liftM2 (+) [0,1] [0,2] = [0,2,1,3] -- liftM2 (+) (Just 1) Nothing = Nothing --liftM2 :: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r -- | Conditional execution of Applicative expressions. For example, -- --
-- when debug (putStrLn "Debugging") ---- -- will output the string Debugging if the Boolean value -- debug is True, and otherwise do nothing. when :: Applicative f => Bool -> f () -> f () -- | Same as >>=, but with the arguments interchanged. (=<<) :: Monad m => (a -> m b) -> m a -> m b infixr 1 =<< -- | Lift a ternary function to actions. liftA3 :: Applicative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d -- | A variant of <*> with the arguments reversed. (<**>) :: Applicative f => f a -> f (a -> b) -> f b infixl 4 <**> -- | Non-empty (and non-strict) list type. data NonEmpty a (:|) :: a -> [a] -> NonEmpty a infixr 5 :| -- | Extract a list of call-sites from the CallStack. -- -- The list is ordered by most recent call. getCallStack :: CallStack -> [([Char], SrcLoc)] -- | Request a CallStack. -- -- NOTE: The implicit parameter ?callStack :: CallStack is an -- implementation detail and should not be considered part of the -- CallStack API, we may decide to change the implementation in -- the future. type HasCallStack = ?callStack :: CallStack -- | This is a valid definition of stimes for an idempotent -- Monoid. -- -- When mappend x x = x, this definition should be preferred, -- because it works in O(1) rather than O(log n) stimesIdempotentMonoid :: (Integral b, Monoid a) => b -> a -> a -- | The SomeException type is the root of the exception type -- hierarchy. When an exception of type e is thrown, behind the -- scenes it is encapsulated in a SomeException. data SomeException SomeException :: e -> SomeException -- | Boolean "and" (&&) :: Bool -> Bool -> Bool infixr 3 && -- | Boolean "or" (||) :: Bool -> Bool -> Bool infixr 2 || -- | Boolean "not" not :: Bool -> Bool -- | The trivial monad transformer, which maps a monad to an equivalent -- monad. data IdentityT (f :: k -> Type) (a :: k) -- | A map of integers to values a. data IntMap a -- | A set of integers. data IntSet -- | General-purpose finite sequences. data Seq a -- | A set of values a. data Set a -- | A class of types that can be fully evaluated. class NFData a -- | rnf should reduce its argument to normal form (that is, fully -- evaluate all sub-components), and then return (). -- --
-- {-# LANGUAGE DeriveGeneric #-}
--
-- import GHC.Generics (Generic, Generic1)
-- import Control.DeepSeq
--
-- data Foo a = Foo a String
-- deriving (Eq, Generic, Generic1)
--
-- instance NFData a => NFData (Foo a)
-- instance NFData1 Foo
--
-- data Colour = Red | Green | Blue
-- deriving Generic
--
-- instance NFData Colour
--
--
-- Starting with GHC 7.10, the example above can be written more
-- concisely by enabling the new DeriveAnyClass extension:
--
--
-- {-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}
--
-- import GHC.Generics (Generic)
-- import Control.DeepSeq
--
-- data Foo a = Foo a String
-- deriving (Eq, Generic, Generic1, NFData, NFData1)
--
-- data Colour = Red | Green | Blue
-- deriving (Generic, NFData)
--
--
-- -- rnf a = seq a () ---- -- However, starting with deepseq-1.4.0.0, the default -- implementation is based on DefaultSignatures allowing for -- more accurate auto-derived NFData instances. If you need the -- previously used exact default rnf method implementation -- semantics, use -- --
-- instance NFData Colour where rnf x = seq x () ---- -- or alternatively -- --
-- instance NFData Colour where rnf = rwhnf ---- -- or -- --
-- {-# LANGUAGE BangPatterns #-}
-- instance NFData Colour where rnf !_ = ()
--
rnf :: NFData a => a -> ()
-- | a variant of deepseq that is useful in some circumstances:
--
-- -- force x = x `deepseq` x ---- -- force x fully evaluates x, and then returns it. Note -- that force x only performs evaluation when the value of -- force x itself is demanded, so essentially it turns shallow -- evaluation into deep evaluation. -- -- force can be conveniently used in combination with -- ViewPatterns: -- --
-- {-# LANGUAGE BangPatterns, ViewPatterns #-}
-- import Control.DeepSeq
--
-- someFun :: ComplexData -> SomeResult
-- someFun (force -> !arg) = {- 'arg' will be fully evaluated -}
--
--
-- Another useful application is to combine force with
-- evaluate in order to force deep evaluation relative to other
-- IO operations:
--
--
-- import Control.Exception (evaluate)
-- import Control.DeepSeq
--
-- main = do
-- result <- evaluate $ force $ pureComputation
-- {- 'result' will be fully evaluated at this point -}
-- return ()
--
--
-- Finally, here's an exception safe variant of the readFile'
-- example:
--
-- -- readFile' :: FilePath -> IO String -- readFile' fn = bracket (openFile fn ReadMode) hClose $ \h -> -- evaluate . force =<< hGetContents h --force :: NFData a => a -> a -- | the deep analogue of $!. In the expression f $!! x, -- x is fully evaluated before the function f is -- applied to it. ($!!) :: NFData a => (a -> b) -> a -> b infixr 0 $!! -- | deepseq: fully evaluates the first argument, before returning -- the second. -- -- The name deepseq is used to illustrate the relationship to -- seq: where seq is shallow in the sense that it only -- evaluates the top level of its argument, deepseq traverses the -- entire data structure evaluating it completely. -- -- deepseq can be useful for forcing pending exceptions, -- eradicating space leaks, or forcing lazy I/O to happen. It is also -- useful in conjunction with parallel Strategies (see the -- parallel package). -- -- There is no guarantee about the ordering of evaluation. The -- implementation may evaluate the components of the structure in any -- order or in parallel. To impose an actual order on evaluation, use -- pseq from Control.Parallel in the parallel -- package. deepseq :: NFData a => a -> b -> b -- | The parameterizable maybe monad, obtained by composing an arbitrary -- monad with the Maybe monad. -- -- Computations are actions that may produce a value or exit. -- -- The return function yields a computation that produces that -- value, while >>= sequences two subcomputations, exiting -- if either computation does. newtype MaybeT (m :: Type -> Type) a MaybeT :: m (Maybe a) -> MaybeT (m :: Type -> Type) a [runMaybeT] :: MaybeT (m :: Type -> Type) a -> m (Maybe a) -- | A monad transformer that adds exceptions to other monads. -- -- ExceptT constructs a monad parameterized over two things: -- --
-- throwM e >> x = throwM e ---- -- In other words, throwing an exception short-circuits the rest of the -- monadic computation. class Monad m => MonadThrow (m :: Type -> Type) -- | A class for monads which allow exceptions to be caught, in particular -- exceptions which were thrown by throwM. -- -- Instances should obey the following law: -- --
-- catch (throwM e) f = f e ---- -- Note that the ability to catch an exception does not guarantee -- that we can deal with all possible exit points from a computation. -- Some monads, such as continuation-based stacks, allow for more than -- just a success/failure strategy, and therefore catch -- cannot be used by those monads to properly implement a function -- such as finally. For more information, see MonadMask. class MonadThrow m => MonadCatch (m :: Type -> Type) -- | A class for monads which provide for the ability to account for all -- possible exit points from a computation, and to mask asynchronous -- exceptions. Continuation-based monads are invalid instances of this -- class. -- -- Instances should ensure that, in the following code: -- --
-- fg = f `finally` g ---- -- The action g is called regardless of what occurs within -- f, including async exceptions. Some monads allow f -- to abort the computation via other effects than throwing an exception. -- For simplicity, we will consider aborting and throwing an exception to -- be two forms of "throwing an error". -- -- If f and g both throw an error, the error thrown by -- fg depends on which errors we're talking about. In a monad -- transformer stack, the deeper layers override the effects of the inner -- layers; for example, ExceptT e1 (Except e2) a represents a -- value of type Either e2 (Either e1 a), so throwing both an -- e1 and an e2 will result in Left e2. If -- f and g both throw an error from the same layer, -- instances should ensure that the error from g wins. -- -- Effects other than throwing an error are also overriden by the deeper -- layers. For example, StateT s Maybe a represents a value of -- type s -> Maybe (a, s), so if an error thrown from -- f causes this function to return Nothing, any -- changes to the state which f also performed will be erased. -- As a result, g will see the state as it was before -- f. Once g completes, f's error will be -- rethrown, so g' state changes will be erased as well. This is -- the normal interaction between effects in a monad transformer stack. -- -- By contrast, lifted-base's version of finally always -- discards all of g's non-IO effects, and g never sees -- any of f's non-IO effects, regardless of the layer ordering -- and regardless of whether f throws an error. This is not the -- result of interacting effects, but a consequence of -- MonadBaseControl's approach. class MonadCatch m => MonadMask (m :: Type -> Type) -- | Runs an action with asynchronous exceptions disabled. The action is -- provided a method for restoring the async. environment to what it was -- at the mask call. See Control.Exception's mask. mask :: MonadMask m => ((forall a. () => m a -> m a) -> m b) -> m b -- | Like mask, but the masked computation is not interruptible (see -- Control.Exception's uninterruptibleMask. WARNING: Only -- use if you need to mask exceptions around an interruptible operation -- AND you can guarantee the interruptible operation will only block for -- a short period of time. Otherwise you render the program/thread -- unresponsive and/or unkillable. uninterruptibleMask :: MonadMask m => ((forall a. () => m a -> m a) -> m b) -> m b -- | A generalized version of bracket which uses ExitCase to -- distinguish the different exit cases, and returns the values of both -- the use and release actions. In practice, this extra -- information is rarely needed, so it is often more convenient to use -- one of the simpler functions which are defined in terms of this one, -- such as bracket, finally, onError, and -- bracketOnError. -- -- This function exists because in order to thread their effects through -- the execution of bracket, monad transformers need values to be -- threaded from use to release and from -- release to the output value. -- -- NOTE This method was added in version 0.9.0 of this library. -- Previously, implementation of functions like bracket and -- finally in this module were based on the mask and -- uninterruptibleMask functions only, disallowing some classes of -- tranformers from having MonadMask instances (notably -- multi-exit-point transformers like ExceptT). If you are a -- library author, you'll now need to provide an implementation for this -- method. The StateT implementation demonstrates most of the -- subtleties: -- --
-- generalBracket acquire release use = StateT $ s0 -> do -- ((b, _s2), (c, s3)) <- generalBracket -- (runStateT acquire s0) -- ((resource, s1) exitCase -> case exitCase of -- ExitCaseSuccess (b, s2) -> runStateT (release resource (ExitCaseSuccess b)) s2 -- -- -- In the two other cases, the base monad overrides use's state -- -- changes and the state reverts to s1. -- ExitCaseException e -> runStateT (release resource (ExitCaseException e)) s1 -- ExitCaseAbort -> runStateT (release resource ExitCaseAbort) s1 -- ) -- ((resource, s1) -> runStateT (use resource) s1) -- return ((b, c), s3) ---- -- The StateT s m implementation of generalBracket -- delegates to the m implementation of generalBracket. -- The acquire, use, and release arguments -- given to StateT's implementation produce actions of type -- StateT s m a, StateT s m b, and StateT s m -- c. In order to run those actions in the base monad, we need to -- call runStateT, from which we obtain actions of type m -- (a, s), m (b, s), and m (c, s). Since each -- action produces the next state, it is important to feed the state -- produced by the previous action to the next action. -- -- In the ExitCaseSuccess case, the state starts at s0, -- flows through acquire to become s1, flows through -- use to become s2, and finally flows through -- release to become s3. In the other two cases, -- release does not receive the value s2, so its action -- cannot see the state changes performed by use. This is fine, -- because in those two cases, an error was thrown in the base monad, so -- as per the usual interaction between effects in a monad transformer -- stack, those state changes get reverted. So we start from s1 -- instead. -- -- Finally, the m implementation of generalBracket -- returns the pairs (b, s) and (c, s). For monad -- transformers other than StateT, this will be some other type -- representing the effects and values performed and returned by the -- use and release actions. The effect part of the -- use result, in this case _s2, usually needs to be -- discarded, since those effects have already been incorporated in the -- release action. -- -- The only effect which is intentionally not incorporated in the -- release action is the effect of throwing an error. In that -- case, the error must be re-thrown. One subtlety which is easy to miss -- is that in the case in which use and release both -- throw an error, the error from release should take priority. -- Here is an implementation for ExceptT which demonstrates how -- to do this. -- --
-- generalBracket acquire release use = ExceptT $ do -- (eb, ec) <- generalBracket -- (runExceptT acquire) -- (eresource exitCase -> case eresource of -- Left e -> return (Left e) -- nothing to release, acquire didn't succeed -- Right resource -> case exitCase of -- ExitCaseSuccess (Right b) -> runExceptT (release resource (ExitCaseSuccess b)) -- ExitCaseException e -> runExceptT (release resource (ExitCaseException e)) -- _ -> runExceptT (release resource ExitCaseAbort)) -- (either (return . Left) (runExceptT . use)) -- return $ do -- -- The order in which we perform those two Either effects determines -- -- which error will win if they are both Lefts. We want the error from -- -- release to win. -- c <- ec -- b <- eb -- return (b, c) --generalBracket :: MonadMask m => m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c) -- | O(n) Convert a lazy Text into a strict Text. toStrict :: Text -> Text -- | A set of values. A set cannot contain duplicate values. data HashSet a -- | A state transformer monad parameterized by: -- --
-- f :: Either String $ Maybe Int -- = -- f :: Either String (Maybe Int) --type (f :: k1 -> k) $ (a :: k1) = f a infixr 2 $ -- | undefined that leaves a warning in code on every usage. undefined :: forall (r :: RuntimeRep) (a :: TYPE r). HasCallStack => a -- | error that takes Text as an argument. error :: forall (r :: RuntimeRep) (a :: TYPE r). HasCallStack => Text -> a -- | s ^? t returns the 1st element t returns, or -- Nothing if t doesn't return anything. It's trivially -- implemented by passing the First monoid to the getter. -- -- Safe head: -- --
-- >>> [] ^? each -- Nothing ---- --
-- >>> [1..3] ^? each -- Just 1 ---- -- Converting Either to Maybe: -- --
-- >>> Left 1 ^? _Right -- Nothing ---- --
-- >>> Right 1 ^? _Right -- Just 1 ---- -- A non-operator version of (^?) is called preview, and -- – like view – it's a bit more general than (^?) (it -- works in MonadReader). If you need the general version, you -- can get it from microlens-mtl; otherwise there's preview -- available in Lens.Micro.Extras. (^?) :: s -> Getting (First a) s a -> Maybe a infixl 8 ^? -- | s ^.. t returns the list of all values that t gets -- from s. -- -- A Maybe contains either 0 or 1 values: -- --
-- >>> Just 3 ^.. _Just -- [3] ---- -- Gathering all values in a list of tuples: -- --
-- >>> [(1,2),(3,4)] ^.. each.each -- [1,2,3,4] --(^..) :: s -> Getting (Endo [a]) s a -> [a] infixl 8 ^.. -- | (^.) applies a getter to a value; in other words, it gets a -- value out of a structure using a getter (which can be a lens, -- traversal, fold, etc.). -- -- Getting 1st field of a tuple: -- --
-- (^. _1) :: (a, b) -> a -- (^. _1) = fst ---- -- When (^.) is used with a traversal, it combines all results -- using the Monoid instance for the resulting type. For instance, -- for lists it would be simple concatenation: -- --
-- >>> ("str","ing") ^. each
-- "string"
--
--
-- The reason for this is that traversals use Applicative, and the
-- Applicative instance for Const uses monoid concatenation
-- to combine “effects” of Const.
--
-- A non-operator version of (^.) is called view, and
-- it's a bit more general than (^.) (it works in
-- MonadReader). If you need the general version, you can get it
-- from microlens-mtl; otherwise there's view available in
-- Lens.Micro.Extras.
(^.) :: s -> Getting a s a -> a
infixl 8 ^.
-- | set is a synonym for (.~).
--
-- Setting the 1st component of a pair:
--
-- -- set _1 :: x -> (a, b) -> (x, b) -- set _1 = \x t -> (x, snd t) ---- -- Using it to rewrite (<$): -- --
-- set mapped :: Functor f => a -> f b -> f a -- set mapped = (<$) --set :: ASetter s t a b -> b -> s -> t -- | (.~) assigns a value to the target. It's the same thing as -- using (%~) with const: -- --
-- l .~ x = l %~ const x ---- -- See set if you want a non-operator synonym. -- -- Here it is used to change 2 fields of a 3-tuple: -- --
-- >>> (0,0,0) & _1 .~ 1 & _3 .~ 3 -- (1,0,3) --(.~) :: ASetter s t a b -> b -> s -> t infixr 4 .~ -- | over is a synonym for (%~). -- -- Getting fmap in a roundabout way: -- --
-- over mapped :: Functor f => (a -> b) -> f a -> f b -- over mapped = fmap ---- -- Applying a function to both components of a pair: -- --
-- over both :: (a -> b) -> (a, a) -> (b, b) -- over both = \f t -> (f (fst t), f (snd t)) ---- -- Using over _2 as a replacement for -- second: -- --
-- >>> over _2 show (10,20) -- (10,"20") --over :: ASetter s t a b -> (a -> b) -> s -> t -- | (%~) applies a function to the target; an alternative -- explanation is that it is an inverse of sets, which turns a -- setter into an ordinary function. mapped %~ -- reverse is the same thing as fmap -- reverse. -- -- See over if you want a non-operator synonym. -- -- Negating the 1st element of a pair: -- --
-- >>> (1,2) & _1 %~ negate -- (-1,2) ---- -- Turning all Lefts in a list to upper case: -- --
-- >>> (mapped._Left.mapped %~ toUpper) [Left "foo", Right "bar"] -- [Left "FOO",Right "bar"] --(%~) :: ASetter s t a b -> (a -> b) -> s -> t infixr 4 %~ -- | Gives access to the 1st field of a tuple (up to 5-tuples). -- -- Getting the 1st component: -- --
-- >>> (1,2,3,4,5) ^. _1 -- 1 ---- -- Setting the 1st component: -- --
-- >>> (1,2,3) & _1 .~ 10 -- (10,2,3) ---- -- Note that this lens is lazy, and can set fields even of -- undefined: -- --
-- >>> set _1 10 undefined :: (Int, Int) -- (10,*** Exception: Prelude.undefined ---- -- This is done to avoid violating a lens law stating that you can get -- back what you put: -- --
-- >>> view _1 . set _1 10 $ (undefined :: (Int, Int)) -- 10 ---- -- The implementation (for 2-tuples) is: -- --
-- _1 f t = (,) <$> f (fst t) -- <*> pure (snd t) ---- -- or, alternatively, -- --
-- _1 f ~(a,b) = (\a' -> (a',b)) <$> f a ---- -- (where ~ means a lazy pattern). -- -- _2, _3, _4, and _5 are also available (see -- below). _1 :: Field1 s t a b => Lens s t a b _2 :: Field2 s t a b => Lens s t a b _3 :: Field3 s t a b => Lens s t a b _4 :: Field4 s t a b => Lens s t a b _5 :: Field5 s t a b => Lens s t a b -- | Lens s t a b is the lowest common denominator of a setter and -- a getter, something that has the power of both; it has a -- Functor constraint, and since both Const and -- Identity are functors, it can be used whenever a getter or a -- setter is needed. -- --
-- t pure ≡ pure -- fmap (t f) . t g ≡ getCompose . t (Compose . fmap f . g) ---- -- The 1st law states that you can't change the shape of the structure or -- do anything funny with elements (traverse elements which aren't in the -- structure, create new elements out of thin air, etc.). The 2nd law -- states that you should be able to fuse 2 identical traversals into -- one. For a more detailed explanation of the laws, see this blog -- post (if you prefer rambling blog posts), or The Essence Of The -- Iterator Pattern (if you prefer papers). -- -- Traversing any value twice is a violation of traversal laws. You can, -- however, traverse values in any order. type Traversal s t a b = forall (f :: Type -> Type). Applicative f => a -> f b -> s -> f t -- | This is a type alias for monomorphic traversals which don't change the -- type of the container (or of the values inside). type Traversal' s a = Traversal s s a a -- | Monadic state transformer. -- -- Maps an old state to a new state inside a state monad. The old state -- is thrown away. -- --
-- Main> :t modify ((+1) :: Int -> Int) -- modify (...) :: (MonadState Int a) => a () ---- -- This says that modify (+1) acts over any Monad that is a -- member of the MonadState class, with an Int state. modify :: MonadState s m => (s -> s) -> m () -- | Retrieves a function of the current environment. asks :: MonadReader r m => (r -> a) -> m a -- | The reader monad transformer, which adds a read-only environment to -- the given monad. -- -- The return function ignores the environment, while -- >>= passes the inherited environment to both -- subcomputations. newtype ReaderT r (m :: Type -> Type) a ReaderT :: (r -> m a) -> ReaderT r (m :: Type -> Type) a [runReaderT] :: ReaderT r (m :: Type -> Type) a -> r -> m a -- | preuse is (^?) (or preview) which implicitly -- operates on the state – it takes the state and applies a traversal (or -- fold) to it to extract the 1st element the traversal points at. -- --
-- preuse l = gets (preview l) --preuse :: MonadState s m => Getting (First a) s a -> m (Maybe a) -- | use is (^.) (or view) which implicitly operates -- on the state; for instance, if your state is a record containing a -- field foo, you can write -- --
-- x <- use foo ---- -- to extract foo from the state. In other words, use is -- the same as gets, but for getters instead of functions. -- -- The implementation of use is straightforward: -- --
-- use l = gets (view l) ---- -- If you need to extract something with a fold or traversal, you need -- preuse. use :: MonadState s m => Getting a s a -> m a -- | preview is a synonym for (^?), generalised for -- MonadReader (just like view, which is a synonym for -- (^.)). -- --
-- >>> preview each [1..5] -- Just 1 --preview :: MonadReader s m => Getting (First a) s a -> m (Maybe a) -- | view is a synonym for (^.), generalised for -- MonadReader (we are able to use it instead of (^.) since -- functions are instances of the MonadReader class): -- --
-- >>> view _1 (1, 2) -- 1 ---- -- When you're using Reader for config and your config type has -- lenses generated for it, most of the time you'll be using view -- instead of asks: -- --
-- doSomething :: (MonadReader Config m) => m Int -- doSomething = do -- thingy <- view setting1 -- same as “asks (^. setting1)” -- anotherThingy <- view setting2 -- ... --view :: MonadReader s m => Getting a s a -> m a -- | Map several constraints over several variables. -- --
-- f :: Each [Show, Read] [a, b] => a -> b -> String -- = -- f :: (Show a, Show b, Read a, Read b) => a -> b -> String ---- -- To specify list with single constraint / variable, don't forget to -- prefix it with ': -- --
-- f :: Each '[Show] [a, b] => a -> b -> String --type family Each (c :: [k -> Constraint]) (as :: [k]) -- | Shorter alias for pure (). -- --
-- >>> pass :: Maybe () -- Just () --pass :: Applicative f => f () -- | Stricter version of $ operator. Default Prelude defines this at -- the toplevel module, so we do as well. -- --
-- >>> const 3 $ Prelude.undefined -- 3 -- -- >>> const 3 $! Prelude.undefined -- *** Exception: Prelude.undefined -- ... --($!) :: (a -> b) -> a -> b infixr 0 $! -- | map generalized to Functor. -- --
-- >>> map not (Just True) -- Just False -- -- >>> map not [True,False,True,True] -- [False,True,False,False] --map :: Functor f => (a -> b) -> f a -> f b -- | Alias for fmap . fmap. Convenient to work with two nested -- Functors. -- --
-- >>> negate <<$>> Just [1,2,3] -- Just [-1,-2,-3] --(<<$>>) :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b) infixl 4 <<$>> -- | Lifted to MonadIO version of newEmptyMVar. newEmptyMVar :: MonadIO m => m (MVar a) -- | Lifted to MonadIO version of newMVar. newMVar :: MonadIO m => a -> m (MVar a) -- | Lifted to MonadIO version of putMVar. putMVar :: MonadIO m => MVar a -> a -> m () -- | Lifted to MonadIO version of readMVar. readMVar :: MonadIO m => MVar a -> m a -- | Lifted to MonadIO version of swapMVar. swapMVar :: MonadIO m => MVar a -> a -> m a -- | Lifted to MonadIO version of takeMVar. takeMVar :: MonadIO m => MVar a -> m a -- | Lifted to MonadIO version of tryPutMVar. tryPutMVar :: MonadIO m => MVar a -> a -> m Bool -- | Lifted to MonadIO version of tryReadMVar. tryReadMVar :: MonadIO m => MVar a -> m (Maybe a) -- | Lifted to MonadIO version of tryTakeMVar. tryTakeMVar :: MonadIO m => MVar a -> m (Maybe a) -- | Lifted to MonadIO version of atomically. atomically :: MonadIO m => STM a -> m a -- | Lifted to MonadIO version of newTVarIO. newTVarIO :: MonadIO m => a -> m (TVar a) -- | Lifted to MonadIO version of readTVarIO. readTVarIO :: MonadIO m => TVar a -> m a -- | Lifted version of exitWith. exitWith :: MonadIO m => ExitCode -> m a -- | Lifted version of exitFailure. exitFailure :: MonadIO m => m a -- | Lifted version of exitSuccess. exitSuccess :: MonadIO m => m a -- | Lifted version of die. die is available since base-4.8, -- but it's more convenient to redefine it instead of using CPP. die :: MonadIO m => String -> m a -- | Lifted version of appendFile. appendFile :: MonadIO m => FilePath -> Text -> m () -- | Lifted version of getLine. getLine :: MonadIO m => m Text -- | Lifted version of openFile. -- -- See also withFile for more information. openFile :: MonadIO m => FilePath -> IOMode -> m Handle -- | Close a file handle -- -- See also withFile for more information. hClose :: MonadIO m => Handle -> m () -- | Opens a file, manipulates it with the provided function and closes the -- handle before returning. The Handle can be written to using the -- hPutStr and hPutStrLn functions. -- -- withFile is essentially the bracket pattern, specialized -- to files. This should be preferred over openFile + -- hClose as it properly deals with (asynchronous) exceptions. In -- cases where withFile is insufficient, for instance because the -- it is not statically known when manipulating the Handle has -- finished, one should consider other safe paradigms for resource usage, -- such as the ResourceT transformer from the resourcet -- package, before resorting to openFile and hClose. withFile :: (MonadIO m, MonadMask m) => FilePath -> IOMode -> (Handle -> m a) -> m a -- | Lifted version of newIORef. newIORef :: MonadIO m => a -> m (IORef a) -- | Lifted version of readIORef. readIORef :: MonadIO m => IORef a -> m a -- | Lifted version of writeIORef. writeIORef :: MonadIO m => IORef a -> a -> m () -- | Lifted version of modifyIORef. modifyIORef :: MonadIO m => IORef a -> (a -> a) -> m () -- | Lifted version of modifyIORef'. modifyIORef' :: MonadIO m => IORef a -> (a -> a) -> m () -- | Lifted version of atomicModifyIORef. atomicModifyIORef :: MonadIO m => IORef a -> (a -> (a, b)) -> m b -- | Lifted version of atomicModifyIORef'. atomicModifyIORef' :: MonadIO m => IORef a -> (a -> (a, b)) -> m b -- | Lifted version of atomicWriteIORef. atomicWriteIORef :: MonadIO m => IORef a -> a -> m () -- | Similar to fromMaybe but with flipped arguments. -- --
-- >>> readMaybe "True" ?: False -- True ---- --
-- >>> readMaybe "Tru" ?: False -- False --(?:) :: Maybe a -> a -> a infixr 0 ?: -- | Specialized version of for_ for Maybe. It's used for -- code readability. Also helps to avoid space leaks: Foldable.mapM_ -- space leak. -- --
-- >>> whenJust Nothing $ \b -> print (not b) -- -- >>> whenJust (Just True) $ \b -> print (not b) -- False --whenJust :: Applicative f => Maybe a -> (a -> f ()) -> f () -- | Monadic version of whenJust. whenJustM :: Monad m => m (Maybe a) -> (a -> m ()) -> m () -- | Performs default Applicative action if Nothing is given. -- Otherwise returns content of Just pured to Applicative. -- --
-- >>> whenNothing Nothing [True, False] -- [True,False] -- -- >>> whenNothing (Just True) [True, False] -- [True] --whenNothing :: Applicative f => Maybe a -> f a -> f a -- | Performs default Applicative action if Nothing is given. -- Do nothing for Just. Convenient for discarding Just -- content. -- --
-- >>> whenNothing_ Nothing $ putTextLn "Nothing!" -- Nothing! -- -- >>> whenNothing_ (Just True) $ putTextLn "Nothing!" --whenNothing_ :: Applicative f => Maybe a -> f () -> f () -- | Monadic version of whenNothing. whenNothingM :: Monad m => m (Maybe a) -> m a -> m a -- | Monadic version of whenNothingM_. whenNothingM_ :: Monad m => m (Maybe a) -> m () -> m () -- | Extracts value from Left or return given default value. -- --
-- >>> fromLeft 0 (Left 3) -- 3 -- -- >>> fromLeft 0 (Right 5) -- 0 --fromLeft :: a -> Either a b -> a -- | Extracts value from Right or return given default value. -- --
-- >>> fromRight 0 (Left 3) -- 0 -- -- >>> fromRight 0 (Right 5) -- 5 --fromRight :: b -> Either a b -> b -- | Maps left part of Either to Maybe. -- --
-- >>> leftToMaybe (Left True) -- Just True -- -- >>> leftToMaybe (Right "aba") -- Nothing --leftToMaybe :: Either l r -> Maybe l -- | Maps right part of Either to Maybe. -- --
-- >>> rightToMaybe (Left True) -- Nothing -- -- >>> rightToMaybe (Right "aba") -- Just "aba" --rightToMaybe :: Either l r -> Maybe r -- | Maps Maybe to Either wrapping default value into -- Left. -- --
-- >>> maybeToRight True (Just "aba") -- Right "aba" -- -- >>> maybeToRight True Nothing -- Left True --maybeToRight :: l -> Maybe r -> Either l r -- | Maps Maybe to Either wrapping default value into -- Right. -- --
-- >>> maybeToLeft True (Just "aba") -- Left "aba" -- -- >>> maybeToLeft True Nothing -- Right True --maybeToLeft :: r -> Maybe l -> Either l r -- | Applies given action to Either content if Left is given. whenLeft :: Applicative f => Either l r -> (l -> f ()) -> f () -- | Monadic version of whenLeft. whenLeftM :: Monad m => m (Either l r) -> (l -> m ()) -> m () -- | Applies given action to Either content if Right is -- given. whenRight :: Applicative f => Either l r -> (r -> f ()) -> f () -- | Monadic version of whenRight. whenRightM :: Monad m => m (Either l r) -> (r -> m ()) -> m () -- | Shorter and more readable alias for flip runReaderT. usingReaderT :: r -> ReaderT r m a -> m a -- | Shorter and more readable alias for flip runReader. usingReader :: r -> Reader r a -> a -- | Shorter and more readable alias for flip runStateT. usingStateT :: s -> StateT s m a -> m (a, s) -- | Shorter and more readable alias for flip runState. usingState :: s -> State s a -> (a, s) -- | Alias for flip evalStateT. It's not shorter but sometimes -- more readable. Done by analogy with using* functions family. evaluatingStateT :: Functor f => s -> StateT s f a -> f a -- | Alias for flip evalState. It's not shorter but sometimes more -- readable. Done by analogy with using* functions family. evaluatingState :: s -> State s a -> a -- | Alias for flip execStateT. It's not shorter but sometimes -- more readable. Done by analogy with using* functions family. executingStateT :: Functor f => s -> StateT s f a -> f s -- | Alias for flip execState. It's not shorter but sometimes more -- readable. Done by analogy with using* functions family. executingState :: s -> State s a -> s -- | Extracts Monoid value from Maybe returning mempty -- if Nothing. -- --
-- >>> maybeToMonoid (Just [1,2,3] :: Maybe [Int]) -- [1,2,3] -- -- >>> maybeToMonoid (Nothing :: Maybe [Int]) -- [] --maybeToMonoid :: Monoid m => Maybe m -> m -- | Type class for types that can be created from one element. -- singleton is lone name for this function. Also constructions -- of different type differ: :[] for lists, two arguments for -- Maps. Also some data types are monomorphic. -- --
-- >>> one True :: [Bool] -- [True] -- -- >>> one 'a' :: Text -- "a" -- -- >>> one (3, "hello") :: HashMap Int String -- fromList [(3,"hello")] --class One x where { type family OneItem x; } -- | Create a list, map, Text, etc from a single element. one :: One x => OneItem x -> x type family OneItem x -- | Very similar to Foldable but also allows instances for -- monomorphic types like Text but forbids instances for -- Maybe and similar. This class is used as a replacement for -- Foldable type class. It solves the following problems: -- --
-- >>> toList @Text "aba" -- "aba" -- -- >>> :t toList @Text "aba" -- toList @Text "aba" :: [Char] --toList :: Container t => t -> [Element t] -- | Checks whether container is empty. -- --
-- >>> null @Text "" -- True -- -- >>> null @Text "aba" -- False --null :: Container t => t -> Bool foldr :: Container t => (Element t -> b -> b) -> b -> t -> b foldl :: Container t => (b -> Element t -> b) -> b -> t -> b foldl' :: Container t => (b -> Element t -> b) -> b -> t -> b length :: Container t => t -> Int elem :: Container t => Element t -> t -> Bool maximum :: Container t => t -> Element t minimum :: Container t => t -> Element t foldMap :: (Container t, Monoid m) => (Element t -> m) -> t -> m fold :: Container t => t -> Element t foldr' :: Container t => (Element t -> b -> b) -> b -> t -> b foldr1 :: Container t => (Element t -> Element t -> Element t) -> t -> Element t foldl1 :: Container t => (Element t -> Element t -> Element t) -> t -> Element t notElem :: Container t => Element t -> t -> Bool all :: Container t => (Element t -> Bool) -> t -> Bool any :: Container t => (Element t -> Bool) -> t -> Bool and :: Container t => t -> Bool or :: Container t => t -> Bool find :: Container t => (Element t -> Bool) -> t -> Maybe (Element t) safeHead :: Container t => t -> Maybe (Element t) -- | Type of element for some container. Implemented as an asscociated type -- family because some containers are monomorphic over element type (like -- Text, IntSet, etc.) so we can't implement nice interface -- using old higher-kinded types approach. Implementing this as an -- associated type family instead of top-level family gives you more -- control over element types. type family Element t -- | Type class for data types that can be converted to List of Pairs. You -- can define ToPairs by just defining toPairs function. -- -- But the following laws should be met: -- --
-- toPairs m ≡ zip (keys m) (elems m) -- keys ≡ map fst . toPairs -- elems ≡ map snd . toPairs --class ToPairs t -- | Converts the structure to the list of the key-value pairs. -- >>> toPairs (HashMap.fromList [(a, "xxx"), -- (b, "yyy")]) [(a,"xxx"),(b,"yyy")] toPairs :: ToPairs t => t -> [(Key t, Val t)] -- | Converts the structure to the list of the keys. -- --
-- >>> keys (HashMap.fromList [('a', "xxx"), ('b', "yyy")])
-- "ab"
--
keys :: ToPairs t => t -> [Key t]
-- | Converts the structure to the list of the values.
--
--
-- >>> elems (HashMap.fromList [('a', "xxx"), ('b', "yyy")])
-- ["xxx","yyy"]
--
elems :: ToPairs t => t -> [Val t]
-- | Similar to foldl' but takes a function with its arguments
-- flipped.
--
-- -- >>> flipfoldl' (/) 5 [2,3] :: Rational -- 15 % 2 --flipfoldl' :: (Container t, Element t ~ a) => (a -> b -> b) -> b -> t -> b -- | Stricter version of sum. -- --
-- >>> sum [1..10] -- 55 -- -- >>> sum (Just 3) -- ... -- • Do not use 'Foldable' methods on Maybe -- Suggestions: -- Instead of -- for_ :: (Foldable t, Applicative f) => t a -> (a -> f b) -> f () -- use -- whenJust :: Applicative f => Maybe a -> (a -> f ()) -> f () -- whenRight :: Applicative f => Either l r -> (r -> f ()) -> f () -- ... -- Instead of -- fold :: (Foldable t, Monoid m) => t m -> m -- use -- maybeToMonoid :: Monoid m => Maybe m -> m -- ... --sum :: (Container t, Num (Element t)) => t -> Element t -- | Stricter version of product. -- --
-- >>> product [1..10] -- 3628800 -- -- >>> product (Right 3) -- ... -- • Do not use 'Foldable' methods on Either -- Suggestions: -- Instead of -- for_ :: (Foldable t, Applicative f) => t a -> (a -> f b) -> f () -- use -- whenJust :: Applicative f => Maybe a -> (a -> f ()) -> f () -- whenRight :: Applicative f => Either l r -> (r -> f ()) -> f () -- ... -- Instead of -- fold :: (Foldable t, Monoid m) => t m -> m -- use -- maybeToMonoid :: Monoid m => Maybe m -> m -- ... --product :: (Container t, Num (Element t)) => t -> Element t -- | Constrained to Container version of traverse_. -- --
-- >>> traverse_ putTextLn ["foo", "bar"] -- foo -- bar --traverse_ :: (Container t, Applicative f) => (Element t -> f b) -> t -> f () -- | Constrained to Container version of for_. -- --
-- >>> for_ [1 .. 5 :: Int] $ \i -> when (even i) (print i) -- 2 -- 4 --for_ :: (Container t, Applicative f) => t -> (Element t -> f b) -> f () -- | Constrained to Container version of mapM_. -- --
-- >>> mapM_ print [True, False] -- True -- False --mapM_ :: (Container t, Monad m) => (Element t -> m b) -> t -> m () -- | Constrained to Container version of forM_. -- --
-- >>> forM_ [True, False] print -- True -- False --forM_ :: (Container t, Monad m) => t -> (Element t -> m b) -> m () -- | Constrained to Container version of sequenceA_. -- --
-- >>> sequenceA_ [putTextLn "foo", print True] -- foo -- True --sequenceA_ :: (Container t, Applicative f, Element t ~ f a) => t -> f () -- | Constrained to Container version of sequence_. -- --
-- >>> sequence_ [putTextLn "foo", print True] -- foo -- True --sequence_ :: (Container t, Monad m, Element t ~ m a) => t -> m () -- | Constrained to Container version of asum. -- --
-- >>> asum [Nothing, Just [False, True], Nothing, Just [True]] -- Just [False,True] --asum :: (Container t, Alternative f, Element t ~ f a) => t -> f a -- | Lifting bind into a monad. Generalized version of concatMap -- that works with a monadic predicate. Old and simpler specialized to -- list version had next type: -- --
-- concatMapM :: Monad m => (a -> m [b]) -> [a] -> m [b] ---- -- Side note: previously it had type -- --
-- concatMapM :: (Applicative q, Monad m, Traversable m) -- => (a -> q (m b)) -> m a -> q (m b) ---- -- Such signature didn't allow to use this function when traversed -- container type and type of returned by function-argument differed. Now -- you can use it like e.g. -- --
-- concatMapM readFile files >>= putTextLn --concatMapM :: (Applicative f, Monoid m, Container (l m), Element (l m) ~ m, Traversable l) => (a -> f m) -> l a -> f m -- | Like concatMapM, but has its arguments flipped, so can be used -- instead of the common fmap concat $ forM pattern. concatForM :: (Applicative f, Monoid m, Container (l m), Element (l m) ~ m, Traversable l) => l a -> (a -> f m) -> f m -- | Monadic and constrained to Container version of and. -- --
-- >>> andM [Just True, Just False] -- Just False -- -- >>> andM [Just True] -- Just True -- -- >>> andM [Just True, Just False, Nothing] -- Just False -- -- >>> andM [Just True, Nothing] -- Nothing -- -- >>> andM [putTextLn "1" >> pure True, putTextLn "2" >> pure False, putTextLn "3" >> pure True] -- 1 -- 2 -- False --andM :: (Container f, Element f ~ m Bool, Monad m) => f -> m Bool -- | Monadic and constrained to Container version of or. -- --
-- >>> orM [Just True, Just False] -- Just True -- -- >>> orM [Just True, Nothing] -- Just True -- -- >>> orM [Nothing, Just True] -- Nothing --orM :: (Container f, Element f ~ m Bool, Monad m) => f -> m Bool -- | Monadic and constrained to Container version of all. -- --
-- >>> allM (readMaybe >=> pure . even) ["6", "10"] -- Just True -- -- >>> allM (readMaybe >=> pure . even) ["5", "aba"] -- Just False -- -- >>> allM (readMaybe >=> pure . even) ["aba", "10"] -- Nothing --allM :: (Container f, Monad m) => (Element f -> m Bool) -> f -> m Bool -- | Monadic and constrained to Container version of any. -- --
-- >>> anyM (readMaybe >=> pure . even) ["5", "10"] -- Just True -- -- >>> anyM (readMaybe >=> pure . even) ["10", "aba"] -- Just True -- -- >>> anyM (readMaybe >=> pure . even) ["aba", "10"] -- Nothing --anyM :: (Container f, Monad m) => (Element f -> m Bool) -> f -> m Bool -- | Destructuring list into its head and tail if possible. This function -- is total. -- --
-- >>> uncons [] -- Nothing -- -- >>> uncons [1..5] -- Just (1,[2,3,4,5]) -- -- >>> uncons (5 : [1..5]) >>= \(f, l) -> pure $ f == length l -- Just True --uncons :: [a] -> Maybe (a, [a]) -- | Performs given action over NonEmpty list if given list is non -- empty. -- --
-- >>> whenNotNull [] $ \(b :| _) -> print (not b) -- -- >>> whenNotNull [False,True] $ \(b :| _) -> print (not b) -- True --whenNotNull :: Applicative f => [a] -> (NonEmpty a -> f ()) -> f () -- | Monadic version of whenNotNull. whenNotNullM :: Monad m => m [a] -> (NonEmpty a -> m ()) -> m () -- | Type that represents exceptions used in cases when a particular -- codepath is not meant to be ever executed, but happens to be executed -- anyway. data Bug Bug :: SomeException -> CallStack -> Bug -- | Pattern synonym to easy pattern matching on exceptions. So intead of -- writing something like this: -- --
-- isNonCriticalExc e
-- | Just (_ :: NodeAttackedError) <- fromException e = True
-- | Just DialogUnexpected{} <- fromException e = True
-- | otherwise = False
--
--
-- you can use Exc pattern synonym:
--
--
-- isNonCriticalExc = case
-- Exc (_ :: NodeAttackedError) -> True -- matching all exceptions of type NodeAttackedError
-- Exc DialogUnexpected{} -> True
-- _ -> False
--
--
-- This pattern is bidirectional. You can use Exc e instead of
-- toException e.
pattern Exc :: Exception e => e -> SomeException
-- | Generate a pure value which, when forced, will synchronously throw the
-- exception wrapped into Bug data type.
bug :: (HasCallStack, Exception e) => e -> a
-- | Throws error for Maybe if Nothing is given. Operates
-- over MonadError.
note :: MonadError e m => e -> Maybe a -> m a
-- | Lifted alias for evaluate with clearer name.
evaluateWHNF :: MonadIO m => a -> m a
-- | Like evaluateWNHF but discards value.
evaluateWHNF_ :: MonadIO m => a -> m ()
-- | Alias for evaluateWHNF . force with clearer name.
evaluateNF :: (NFData a, MonadIO m) => a -> m a
-- | Alias for evaluateWHNF . rnf. Similar to evaluateNF
-- but discards resulting value.
evaluateNF_ :: (NFData a, MonadIO m) => a -> m ()
-- | Monadic version of when.
--
--
-- >>> whenM (pure False) $ putTextLn "No text :("
--
-- >>> whenM (pure True) $ putTextLn "Yes text :)"
-- Yes text :)
--
-- >>> whenM (Just True) (pure ())
-- Just ()
--
-- >>> whenM (Just False) (pure ())
-- Just ()
--
-- >>> whenM Nothing (pure ())
-- Nothing
--
whenM :: Monad m => m Bool -> m () -> m ()
-- | Monadic version of unless.
--
--
-- >>> unlessM (pure False) $ putTextLn "No text :("
-- No text :(
--
-- >>> unlessM (pure True) $ putTextLn "Yes text :)"
--
unlessM :: Monad m => m Bool -> m () -> m ()
-- | Monadic version of if-then-else.
--
-- -- >>> ifM (pure True) (putTextLn "True text") (putTextLn "False text") -- True text --ifM :: Monad m => m Bool -> m a -> m a -> m a -- | Monadic version of guard. Occasionally useful. Here some -- complex but real-life example: -- --
-- findSomePath :: IO (Maybe FilePath) -- -- somePath :: MaybeT IO FilePath -- somePath = do -- path <- MaybeT findSomePath -- guardM $ liftIO $ doesDirectoryExist path -- return path --guardM :: MonadPlus m => m Bool -> m () -- | Like nub but runs in O(n * log n) time and requires -- Ord. -- --
-- >>> ordNub [3, 3, 3, 2, 2, -1, 1] -- [3,2,-1,1] --ordNub :: Ord a => [a] -> [a] -- | Like nub but runs in O(n * log_16(n)) time and -- requires Hashable. -- --
-- >>> hashNub [3, 3, 3, 2, 2, -1, 1] -- [3,2,-1,1] --hashNub :: (Eq a, Hashable a) => [a] -> [a] -- | Like ordNub but also sorts a list. -- --
-- >>> sortNub [3, 3, 3, 2, 2, -1, 1] -- [-1,1,2,3] --sortNub :: Ord a => [a] -> [a] -- | Like hashNub but has better performance and also doesn't save -- the order. -- --
-- >>> unstableNub [3, 3, 3, 2, 2, -1, 1] -- [1,2,3,-1] --unstableNub :: (Eq a, Hashable a) => [a] -> [a] -- | Support class to overload writing of string like values. class Print a -- | Write a string like value a to a supplied Handle. hPutStr :: (Print a, MonadIO m) => Handle -> a -> m () -- | Write a string like value a to a supplied Handle, -- appending a newline character. hPutStrLn :: (Print a, MonadIO m) => Handle -> a -> m () -- | Write a string like value to stdout/. putStr :: (Print a, MonadIO m) => a -> m () -- | Write a string like value to stdout appending a newline -- character. putStrLn :: (Print a, MonadIO m) => a -> m () -- | Lifted version of print. print :: forall a m. (MonadIO m, Show a) => a -> m () -- | Lifted version of hPrint hPrint :: (MonadIO m, Show a) => Handle -> a -> m () -- | Specialized to Text version of putStr or forcing type -- inference. putText :: MonadIO m => Text -> m () -- | Specialized to Text version of putStrLn or forcing type -- inference. putTextLn :: MonadIO m => Text -> m () -- | Specialized to Text version of putStr or forcing type -- inference. putLText :: MonadIO m => Text -> m () -- | Specialized to Text version of putStrLn or forcing type -- inference. putLTextLn :: MonadIO m => Text -> m () -- | Similar to undefined but data type. data Undefined Undefined :: Undefined -- | Version of trace that leaves a warning and takes Text. trace :: Text -> a -> a -- | Version of traceShow that leaves a warning. traceShow :: Show a => a -> b -> b -- | Version of traceShowId that leaves a warning. traceShowId :: Show a => a -> a -- | Version of traceId that leaves a warning. Useful to tag printed -- data, for instance: -- --
-- traceIdWith (x -> "My data: " <> show x) (veryLargeExpression) ---- -- This is especially useful with custom formatters: -- --
-- traceIdWith (x -> "My data: " <> pretty x) (veryLargeExpression) --traceIdWith :: (a -> Text) -> a -> a -- | Version of traceShowId that leaves a warning. Useful to tag -- printed data, for instance: -- --
-- traceShowIdWith ("My data: ", ) (veryLargeExpression)
--
traceShowIdWith :: Show s => (a -> s) -> a -> a
-- | Version of traceShowM that leaves a warning.
traceShowM :: (Show a, Monad m) => a -> m ()
-- | Version of traceM that leaves a warning and takes Text.
traceM :: Monad m => Text -> m ()
-- | Version of traceId that leaves a warning.
traceId :: Text -> Text
-- | Type class for converting other strings to String.
class ToString a
toString :: ToString a => a -> String
-- | Type class for converting other strings to Text.
class ToLText a
toLText :: ToLText a => a -> Text
-- | Type class for converting other strings to Text.
class ToText a
toText :: ToText a => a -> Text
-- | Type class for conversion to utf8 representation of text.
class ConvertUtf8 a b
-- | Encode as utf8 string (usually ByteString).
--
-- -- >>> encodeUtf8 @Text @ByteString "патак" -- "\208\191\208\176\209\130\208\176\208\186" --encodeUtf8 :: ConvertUtf8 a b => a -> b -- | Decode from utf8 string. -- --
-- >>> decodeUtf8 @Text @ByteString "\208\191\208\176\209\130\208\176\208\186" -- "\1087\1072\1090\1072\1082" -- -- >>> putStrLn $ decodeUtf8 @Text @ByteString "\208\191\208\176\209\130\208\176\208\186" -- патак --decodeUtf8 :: ConvertUtf8 a b => b -> a -- | Decode as utf8 string but returning execption if byte sequence is -- malformed. -- --
-- >>> decodeUtf8 @Text @ByteString "\208\208\176\209\130\208\176\208\186" -- "\65533\1072\1090\1072\1082" ---- --
-- >>> decodeUtf8Strict @Text @ByteString "\208\208\176\209\130\208\176\208\186" -- Left Cannot decode byte '\xd0': Data.Text.Internal.Encoding.decodeUtf8: Invalid UTF-8 stream --decodeUtf8Strict :: ConvertUtf8 a b => b -> Either UnicodeException a -- | Type synonym for ByteString. type LByteString = ByteString -- | Type synonym for Text. type LText = Text -- | Polymorhpic version of readEither. -- --
-- >>> readEither @Text @Int "123" -- Right 123 -- -- >>> readEither @Text @Int "aa" -- Left "Prelude.read: no parse" --readEither :: (ToString a, Read b) => a -> Either Text b -- | Generalized version of show. show :: forall b a. (Show a, IsString b) => a -> b -- | Map several constraints over a single variable. Note, that With a -- b ≡ Each a '[b] -- --
-- a :: With [Show, Read] a => a -> a -- = -- a :: (Show a, Read a) => a -> a --type With (a :: [k -> Constraint]) (b :: k) = a <+> b -- | This type class allows to implement variadic composition operator. class SuperComposition a b c | a b -> c -- | Allows to apply function to result of another function with multiple -- arguments. -- --
-- >>> (show ... (+)) 1 2 -- "3" -- -- >>> show ... 5 -- "5" -- -- >>> (null ... zip5) [1] [2] [3] [] [5] -- True ---- -- Inspired by -- http://stackoverflow.com/questions/9656797/variadic-compose-function. -- --
execStateT m s = liftM snd -- (runStateT m s)
evalStateT m s = liftM fst -- (runStateT m s)
-- >>> 2^100 :: Natural -- 1267650600228229401496703205376 ---- -- Operations whose result would be negative throw -- (Underflow :: ArithException), -- --
-- >>> -1 :: Natural -- *** Exception: arithmetic underflow --data Natural -- | The Maybe type encapsulates an optional value. A value of type -- Maybe a either contains a value of type a -- (represented as Just a), or it is empty (represented -- as Nothing). Using Maybe is a good way to deal with -- errors or exceptional cases without resorting to drastic measures such -- as error. -- -- The Maybe type is also a monad. It is a simple kind of error -- monad, where all errors are represented by Nothing. A richer -- error monad can be built using the Either type. data Maybe a Nothing :: Maybe a Just :: a -> Maybe a -- | A space-efficient representation of a Word8 vector, supporting -- many efficient operations. -- -- A ByteString contains 8-bit bytes, or by using the operations -- from Data.ByteString.Char8 it can be interpreted as containing -- 8-bit characters. data ByteString -- | A Map from keys k to values a. -- -- The Semigroup operation for Map is union, which -- prefers values from the left operand. If m1 maps a key -- k to a value a1, and m2 maps the same key -- to a different value a2, then their union m1 <> -- m2 maps k to a1. data Map k a -- | From a Dict, takes a value in an environment where the instance -- witnessed by the Dict is in scope, and evaluates it. -- -- Essentially a deconstruction of a Dict into its -- continuation-style form. -- -- Can also be used to deconstruct an entailment, a :- b, -- using a context a. -- --
-- withDict :: Dict c -> (c => r) -> r -- withDict :: a => (a :- c) -> (c => r) -> r --withDict :: HasDict c e => e -> (c => r) -> r -- | A set of values a. data Set a -- | A class for types with a default value. class Default a -- | The default value for this type. def :: Default a => a -- | Note that calling given entrypoints involves constructing -- UParam. pbsUParam :: forall (ctorName :: Symbol). KnownSymbol ctorName => ParamBuildingStep -- | Make up UParam from ADT sum. -- -- Entry points template will consist of (constructorName, -- constructorFieldType) pairs. Each constructor is expected to have -- exactly one field. uparamFromAdt :: UParamLinearize up => up -> UParam (UParamLinearized up) -- | Like caseUParam, but accepts a tuple of clauses, not a -- Rec. caseUParamT :: forall (entries :: [EntrypointKind]) (inp :: [Type]) (out :: [Type]) clauses. (clauses ~ Rec (CaseClauseU inp out) entries, RecFromTuple clauses, CaseUParam entries) => IsoRecTuple clauses -> UParamFallback inp out -> (UParam entries : inp) :-> out -- | Pattern-match on given UParam entries. -- -- You have to provide all case branches and a fallback action on case -- when entrypoint is not found. caseUParam :: forall (entries :: [EntrypointKind]) (inp :: [Type]) (out :: [Type]). (CaseUParam entries, RequireUniqueEntrypoints entries) => Rec (CaseClauseU inp out) entries -> UParamFallback inp out -> (UParam entries : inp) :-> out -- | Default implementation for UParamFallback, simply reports an -- error. uparamFallbackFail :: forall (inp :: [Type]) (out :: [Type]). UParamFallback inp out -- | Helper instruction which extracts content of UParam. unwrapUParam :: forall (entries :: [EntrypointKind]) (s :: [Type]). (UParam entries : s) :-> ((MText, ByteString) : s) -- | Construct a UParam safely. mkUParam :: forall a (name :: Symbol) (entries :: [EntrypointKind]). (NicePackedValue a, LookupEntrypoint name entries ~ a, RequireUniqueEntrypoints entries) => Label name -> a -> UParam entries -- | An entrypoint is described by two types: its name and type of -- argument. type EntrypointKind = (Symbol, Type) -- | A convenient alias for type-level name-something pair. type (n :: Symbol) ?: (a :: k) = '(n, a) -- | Encapsulates parameter for one of entry points. It keeps entrypoint -- name and corresponding argument serialized. -- -- In Haskell world, we keep an invariant of that contained value relates -- to one of entry points from entries list. newtype UParam (entries :: [EntrypointKind]) UParamUnsafe :: (MText, ByteString) -> UParam (entries :: [EntrypointKind]) -- | Pseudo value for UParam type variable. type SomeInterface = '[ '("SomeEntrypoints", Void)] -- | Homomorphic version of UParam, forgets the exact interface. type UParam_ = UParam SomeInterface -- | Get type of entrypoint argument by its name. type family LookupEntrypoint (name :: Symbol) (entries :: [EntrypointKind]) -- | Ensure that given entry points do no contain duplicated names. type family RequireUniqueEntrypoints (entries :: [EntrypointKind]) -- | This type can store any value that satisfies a certain constraint. data ConstrainedSome (c :: Type -> Constraint) [ConstrainedSome] :: forall (c :: Type -> Constraint) a. c a => a -> ConstrainedSome c -- | This class is needed to implement unpackUParam. class UnpackUParam (c :: Type -> Constraint) (entries :: [EntrypointKind]) -- | Turn UParam into a Haskell value. Since we don't know its type -- in compile time, we have to erase it using ConstrainedSome. The -- user of this function can require arbitrary constraint to hold -- (depending on how they want to use the result). unpackUParam :: UnpackUParam c entries => UParam entries -> Either EntrypointLookupError (MText, ConstrainedSome c) data EntrypointLookupError NoSuchEntrypoint :: MText -> EntrypointLookupError ArgumentUnpackFailed :: EntrypointLookupError -- | Implementations of some entry points. -- -- Note that this thing inherits properties of Rec, e.g. you can -- Data.Vinyl.Core.rappend implementations for two entrypoint -- sets when assembling scattered parts of a contract. type EntrypointsImpl (inp :: [Type]) (out :: [Type]) (entries :: [EntrypointKind]) = Rec CaseClauseU inp out entries -- | An action invoked when user-provided entrypoint is not found. type UParamFallback (inp :: [Type]) (out :: [Type]) = (MText, ByteString) : inp :-> out -- | Make up a "case" over entry points. class CaseUParam (entries :: [EntrypointKind]) -- | Constraint required by uparamFromAdt. type UParamLinearize p = (Generic p, GUParamLinearize Rep p) -- | Entry points template derived from given ADT sum. type UParamLinearized p = GUParamLinearized Rep p entryCaseSimple_ :: forall cp (out :: [Type]) (inp :: [Type]). (InstrCaseC cp, RMap (CaseClauses cp), DocumentEntrypoints PlainEntrypointsKind cp, NiceParameterFull cp, RequireFlatParamEps cp) => Rec (CaseClauseL inp out) (CaseClauses cp) -> (cp : inp) :-> out -- | Whether finalizeParamCallingDoc has already been applied to -- these steps. areFinalizedParamBuildingSteps :: [ParamBuildingStep] -> Bool -- | Wrapper for documenting single entrypoint which parameter isn't going -- to be unwrapped from some datatype. -- -- entryCase unwraps a datatype, however, sometimes we want to -- have entrypoint parameter to be not wrapped into some datatype. documentEntrypoint :: forall kind (epName :: Symbol) param (s :: [Type]) (out :: [Type]). (KnownSymbol epName, DocItem (DEntrypoint kind), TypeHasDoc param, HasAnnotation param, KnownValue param) => ((param : s) :-> out) -> (param : s) :-> out -- | Go over contract code and update every occurrence of -- DEntrypointArg documentation item, adding the given step to its -- "how to build parameter" description. clarifyParamBuildingSteps :: forall (inp :: [Type]) (out :: [Type]). ParamBuildingStep -> (inp :-> out) -> inp :-> out mkDEntrypointArgSimple :: (KnownValue t, HasAnnotation t, TypeHasDoc t) => DEntrypointArg mkDEpUType :: (KnownValue t, HasAnnotation t) => Type emptyDEpArg :: DEntrypointArg constructDEpArg :: (TypeHasDoc arg, HasAnnotation arg, KnownValue arg) => DEntrypointArg -- | Make a ParamBuildingStep that tells about wrapping an argument -- into a constructor with given name and uses given ParamBuilder -- as description of Michelson part. mkPbsWrapIn :: Text -> ParamBuilder -> ParamBuildingStep -- | Mark code as part of entrypoint with given name. -- -- This is automatically called at most of the appropriate situations, -- like entryCase calls. entrypointSection :: forall kind (i :: [Type]) (o :: [Type]). EntrypointKindHasDoc kind => Text -> Proxy kind -> (i :-> o) -> i :-> o -- | Default implementation of docItemToMarkdown for entrypoints. diEntrypointToMarkdown :: HeaderLevel -> DEntrypoint level -> Markdown -- | Pattern that checks whether given SomeDocItem hides -- DEntrypoint inside (of any entrypoint kind). -- -- In case a specific kind is necessary, use plain (cast -> Just -- DEntrypoint{..}) construction instead. pattern DEntrypointDocItem :: () => DEntrypoint kind -> SomeDocItem -- | Gathers information about single entrypoint. -- -- We assume that entry points might be of different kinds, which is -- designated by phantom type parameter. For instance, you may want to -- have several groups of entry points corresponding to various parts of -- a contract - specifying different kind type argument for each -- of those groups will allow you defining different DocItem -- instances with appropriate custom descriptions for them. data DEntrypoint kind DEntrypoint :: Text -> SubDoc -> DEntrypoint kind [depName] :: DEntrypoint kind -> Text [depSub] :: DEntrypoint kind -> SubDoc -- | Describes location of entrypoints of the given kind. -- -- All such entrypoints will be placed under the same "entrypoints" -- section, and this instance defines characteristics of this section. class Typeable ep => EntrypointKindHasDoc ep -- | Position of the respective entrypoints section in the doc. This shares -- the same positions space with all other doc items. entrypointKindPos :: EntrypointKindHasDoc ep => Natural -- | Name of the respective entrypoints section. entrypointKindSectionName :: EntrypointKindHasDoc ep => Text -- | Description in the respective entrypoints section. entrypointKindSectionDescription :: EntrypointKindHasDoc ep => Maybe Markdown -- | Default value for DEntrypoint type argument. data PlainEntrypointsKind -- | Describes the behaviour common for all entrypoints. -- -- For instance, if your contract runs some checks before calling any -- entrypoint, you probably want to wrap those checks into -- entrypointSection "Prior checks" (Proxy -- @CommonContractBehaviourKind). data CommonContractBehaviourKind -- | Describes the behaviour common for entrypoints of given kind. -- -- This has very special use cases, like contracts with mix of -- upgradeable and permanent entrypoints. data CommonEntrypointsBehaviourKind (kind :: k) -- | Inserts a reference to an existing entrypoint. -- -- This helps to avoid duplication in the generated documentation, in -- order not to overwhelm the reader. data DEntrypointReference DEntrypointReference :: Text -> Anchor -> DEntrypointReference -- | When describing the way of parameter construction - piece of -- incremental builder for this description. newtype ParamBuilder ParamBuilder :: (Markdown -> Markdown) -> ParamBuilder -- | Argument stands for previously constructed parameter piece, and -- returned value - a piece constructed after our step. [unParamBuilder] :: ParamBuilder -> Markdown -> Markdown data ParamBuildingDesc ParamBuildingDesc :: Markdown -> ParamBuilder -> ParamBuilder -> ParamBuildingDesc -- | Plain english description of this step. [pbdEnglish] :: ParamBuildingDesc -> Markdown -- | How to construct parameter in Haskell code. [pbdHaskell] :: ParamBuildingDesc -> ParamBuilder -- | How to construct parameter working on raw Michelson. [pbdMichelson] :: ParamBuildingDesc -> ParamBuilder -- | Describes a parameter building step. -- -- This can be wrapping into (Haskell) constructor, or a more complex -- transformation. data ParamBuildingStep -- | Wraps something into constructor with given name. Constructor should -- be the one which corresponds to an entrypoint defined via field -- annotation, for more complex cases use PbsCustom. PbsWrapIn :: Text -> ParamBuildingDesc -> ParamBuildingStep -- | Directly call an entrypoint marked with a field annotation. PbsCallEntrypoint :: EpName -> ParamBuildingStep -- | Other action. PbsCustom :: ParamBuildingDesc -> ParamBuildingStep -- | This entrypoint cannot be called, which is possible when an explicit -- default entrypoint is present. This is not a true entrypoint but just -- some intermediate node in or tree and neither it nor any of -- its parents are marked with a field annotation. -- -- It contains dummy ParamBuildingSteps which were assigned before -- entrypoints were taken into account. PbsUncallable :: [ParamBuildingStep] -> ParamBuildingStep -- | Describes argument of an entrypoint. data DEntrypointArg DEntrypointArg :: Maybe DType -> [ParamBuildingStep] -> Type -> DEntrypointArg -- | Argument of the entrypoint. Pass Nothing if no argument is -- required. [epaArg] :: DEntrypointArg -> Maybe DType -- | Describes a way to lift an entrypoint argument into full parameter -- which can be passed to the contract. -- -- Steps are supposed to be applied in the order opposite to one in which -- they are given. E.g. suppose that an entrypoint is called as Run -- (Service1 arg); then the first step (actual last) should describe -- wrapping into Run constructor, and the second step (actual -- first) should be about wrapping into Service1 constructor. [epaBuilding] :: DEntrypointArg -> [ParamBuildingStep] -- | Untyped representation of entrypoint, used for printing its michelson -- type representation. [epaType] :: DEntrypointArg -> Type -- | Pick a type documentation from CtorField. class KnownSymbol con => DeriveCtorFieldDoc (con :: Symbol) (cf :: CtorField) deriveCtorFieldDoc :: DeriveCtorFieldDoc con cf => DEntrypointArg -- | Constraint for documentEntrypoints. type DocumentEntrypoints kind a = (Generic a, GDocumentEntrypoints kind Rep a) -- | Provides arror for convenient entrypoint documentation class EntryArrow (kind :: k) (name :: Symbol) body -- | Lift entrypoint implementation. -- -- Entrypoint names should go with "e" prefix. (#->) :: EntryArrow kind name body => (Label name, Proxy kind) -> body -> body type family RequireFlatParamEps cp type family RequireFlatEpDerivation (cp :: t) deriv -- | Utility to create EntrypointsFields from an entrypoint name -- (epName) and an EntrypointLambda implementation. Note -- that you need to merge multiple of these (with <>) if -- your field contains more than one entrypoint lambda. mkStoreEp :: forall (epName :: Symbol) epParam epStore. Label epName -> EntrypointLambda epParam epStore -> EntrypointsField epParam epStore -- | Turn submap operations into operations on a part of the submap value. -- -- Normally, if you need this set of operations, it would be better to -- split your submap into several separate submaps, each operating with -- its own part of the value. This set of operations is pretty -- inefficient and exists only as a temporary measure, if due to -- historical reasons you have to leave storage format intact. -- -- This implementation puts no distinction between value == -- Nothing and value == Just defValue cases. Getters, when -- notice a value equal to the default value, report its absence. Setters -- tend to remove the value from submap when possible. -- -- LIso (Maybe value) value and LIso (Maybe subvalue) -- subvalue arguments describe how to get a value if it was absent -- in map and how to detect when it can be safely removed from map. -- -- Example of use: zoomStoreSubmapOps #mySubmap nonDefIso nonDefIso -- storeSubmapOps storeFieldOpsADT zoomStoreSubmapOps :: forall store (submapName :: Symbol) (nameInSubmap :: Symbol) key value subvalue. (NiceConstant value, NiceConstant subvalue) => Label submapName -> LIso (Maybe value) value -> LIso (Maybe subvalue) subvalue -> StoreSubmapOps store submapName key value -> StoreFieldOps value nameInSubmap subvalue -> StoreSubmapOps store nameInSubmap key subvalue composeStoreEntrypointOps :: forall (nameInStore :: Symbol) store substore (epName :: Symbol) epParam epStore. Label nameInStore -> StoreFieldOps store nameInStore substore -> StoreEntrypointOps substore epName epParam epStore -> StoreEntrypointOps store epName epParam epStore -- | Chain implementations of two submap operations sets. Used to provide -- shortcut access to a nested submap. -- -- This is very inefficient since on each access to substore it has to be -- serialized/deserialized. Use this implementation only if due to -- historical reasons migrating storage is difficult. -- -- LIso (Maybe substore) substore argument describes how to get -- substore value if it was absent in map and how to detect when -- it can be safely removed. -- -- Example of use: sequenceStoreSubmapOps #mySubmap nonDefIso -- storeSubmapOps storeSubmapOps sequenceStoreSubmapOps :: forall store substore value (name :: Symbol) (subName :: Symbol) key1 key2. (NiceConstant substore, KnownValue value) => Label name -> LIso (Maybe substore) substore -> StoreSubmapOps store name key1 substore -> StoreSubmapOps substore subName key2 value -> StoreSubmapOps store subName (key1, key2) value -- | Chain implementations of field and submap operations. composeStoreSubmapOps :: forall (nameInStore :: Symbol) store substore (mname :: Symbol) key value. Label nameInStore -> StoreFieldOps store nameInStore substore -> StoreSubmapOps substore mname key value -> StoreSubmapOps store mname key value -- | Chain two implementations of field operations. -- -- Suits for a case when your store does not contain its fields directly -- rather has a nested structure. composeStoreFieldOps :: forall (nameInStore :: Symbol) store substore (nameInSubstore :: Symbol) field. Label nameInStore -> StoreFieldOps store nameInStore substore -> StoreFieldOps substore nameInSubstore field -> StoreFieldOps store nameInSubstore field -- | Change submap operations so that they work on a modified value. mapStoreSubmapOpsValue :: forall value1 value2 store (name :: Symbol) key. KnownValue value1 => LIso value1 value2 -> StoreSubmapOps store name key value1 -> StoreSubmapOps store name key value2 -- | Change submap operations so that they work on a modified key. mapStoreSubmapOpsKey :: forall key2 key1 store (name :: Symbol) value. Lambda key2 key1 -> StoreSubmapOps store name key1 value -> StoreSubmapOps store name key2 value -- | Change field operations so that they work on a modified field. -- -- For instance, to go from StoreFieldOps Storage "name" Integer -- to StoreFieldOps Storage "name" (value :! Integer) you can -- use mapStoreFieldOps (namedIso #value) mapStoreFieldOps :: forall field1 field2 store (name :: Symbol). LIso field1 field2 -> StoreFieldOps store name field1 -> StoreFieldOps store name field2 -- | Pretend that given StoreEntrypointOps implementation is made up -- for entrypoint with name desiredName, not its actual name. -- Logic of the implementation remains the same. -- -- See also storeSubmapOpsReferTo. storeEntrypointOpsReferTo :: forall (epName :: Symbol) store epParam epStore (desiredName :: Symbol). Label epName -> StoreEntrypointOps store epName epParam epStore -> StoreEntrypointOps store desiredName epParam epStore -- | Pretend that given StoreFieldOps implementation is made up for -- field with name desiredName, not its actual name. Logic of -- the implementation remains the same. -- -- See also storeSubmapOpsReferTo. storeFieldOpsReferTo :: forall (name :: Symbol) storage field (desiredName :: Symbol). Label name -> StoreFieldOps storage name field -> StoreFieldOps storage desiredName field -- | Pretend that given StoreSubmapOps implementation is made up for -- submap with name desiredName, not its actual name. Logic of -- the implementation remains the same. -- -- Use case: imagine that your code requires access to submap named -- X, but in your storage that submap is called Y. Then -- you implement the instance which makes X refer to Y: -- --
-- instance StoreHasSubmap Store X Key Value where -- storeSubmapOps = storeSubmapOpsReferTo #Y storeSubmapOpsForY --storeSubmapOpsReferTo :: forall (name :: Symbol) storage key value (desiredName :: Symbol). Label name -> StoreSubmapOps storage name key value -> StoreSubmapOps storage desiredName key value -- | Implementation of StoreHasEntrypoint for a data type which has -- an instance of StoreHasEntrypoint inside. For instance, it can -- be used for top-level storage. storeEntrypointOpsDeeper :: forall store (nameInStore :: Symbol) substore (epName :: Symbol) epParam epStore. (HasFieldOfType store nameInStore substore, StoreHasEntrypoint substore epName epParam epStore) => Label nameInStore -> StoreEntrypointOps store epName epParam epStore -- | Implementation of StoreHasSubmap for a data type which has an -- instance of StoreHasSubmap inside. For instance, it can be used -- for top-level storage. storeSubmapOpsDeeper :: forall storage (bigMapPartName :: Symbol) fields (mname :: Symbol) key value. (HasFieldOfType storage bigMapPartName fields, StoreHasSubmap fields mname key value) => Label bigMapPartName -> StoreSubmapOps storage mname key value -- | Implementation of StoreHasField for a data type which has an -- instance of StoreHasField inside. For instance, it can be used -- for top-level storage. storeFieldOpsDeeper :: forall storage (fieldsPartName :: Symbol) fields (fname :: Symbol) ftype. (HasFieldOfType storage fieldsPartName fields, StoreHasField fields fname ftype) => Label fieldsPartName -> StoreFieldOps storage fname ftype -- | Implementation of StoreHasEntrypoint for a datatype that has a -- StoreHasSubmap that contains the entrypoint and a -- StoreHasField for the field such entrypoint operates on. storeEntrypointOpsSubmapField :: forall store (epmName :: Symbol) epParam epStore (epsName :: Symbol) (epName :: Symbol). (StoreHasSubmap store epmName MText (EntrypointLambda epParam epStore), StoreHasField store epsName epStore, KnownValue epParam, KnownValue epStore) => Label epmName -> Label epsName -> StoreEntrypointOps store epName epParam epStore -- | Implementation of StoreHasEntrypoint for a datatype that has a -- StoreHasField for an EntrypointsField that contains the -- entrypoint and a StoreHasField for the field such entrypoint -- operates on. storeEntrypointOpsFields :: forall store (epmName :: Symbol) epParam epStore (epsName :: Symbol) (epName :: Symbol). (StoreHasField store epmName (EntrypointsField epParam epStore), StoreHasField store epsName epStore, KnownValue epParam, KnownValue epStore) => Label epmName -> Label epsName -> StoreEntrypointOps store epName epParam epStore -- | Implementation of StoreHasEntrypoint for a datatype keeping a -- pack of fields, among which one has contains the entrypoint and -- another is what such entrypoint operates on. storeEntrypointOpsADT :: forall store (epmName :: Symbol) epParam epStore (epsName :: Symbol) (epName :: Symbol). (HasFieldOfType store epmName (EntrypointsField epParam epStore), HasFieldOfType store epsName epStore, KnownValue epParam, KnownValue epStore) => Label epmName -> Label epsName -> StoreEntrypointOps store epName epParam epStore -- | Implementation of StoreHasField for case of datatype keeping a -- pack of fields. storeFieldOpsADT :: forall dt (fname :: Symbol) ftype. HasFieldOfType dt fname ftype => StoreFieldOps dt fname ftype -- | Update the sub-storage that the entrypoint operates on. stSetEpStore :: forall store (epName :: Symbol) epParam epStore (s :: [Type]). StoreHasEntrypoint store epName epParam epStore => Label epName -> (epStore : (store : s)) :-> (store : s) -- | Get the sub-storage that the entrypoint operates on, preserving the -- storage itself on the stack. stGetEpStore :: forall store (epName :: Symbol) epParam epStore (s :: [Type]). StoreHasEntrypoint store epName epParam epStore => Label epName -> (store : s) :-> (epStore : (store : s)) -- | Pick the sub-storage that the entrypoint operates on. stToEpStore :: forall store (epName :: Symbol) epParam epStore (s :: [Type]). StoreHasEntrypoint store epName epParam epStore => Label epName -> (store : s) :-> (epStore : s) -- | Stores the entrypoint lambda in the storage. Fails if already set. stSetEpLambda :: forall store (epName :: Symbol) epParam epStore (s :: [Type]). StoreHasEntrypoint store epName epParam epStore => Label epName -> (EntrypointLambda epParam epStore : (store : s)) :-> (store : s) -- | Get stored entrypoint lambda, preserving the storage itself on the -- stack. stGetEpLambda :: forall store (epName :: Symbol) epParam epStore (s :: [Type]). StoreHasEntrypoint store epName epParam epStore => Label epName -> (store : s) :-> (EntrypointLambda epParam epStore : (store : s)) -- | Pick stored entrypoint lambda. stToEpLambda :: forall store (epName :: Symbol) epParam epStore (s :: [Type]). StoreHasEntrypoint store epName epParam epStore => Label epName -> (store : s) :-> (EntrypointLambda epParam epStore : s) -- | Extracts and executes the epName entrypoint lambda from -- storage, returing the updated full storage (store) and the -- produced Operations. stEntrypoint :: forall store (epName :: Symbol) epParam epStore (s :: [Type]). StoreHasEntrypoint store epName epParam epStore => Label epName -> (epParam : (store : s)) :-> (([Operation], store) : s) -- | Update storage field. stSetField :: forall store (fname :: Symbol) ftype (s :: [Type]). StoreHasField store fname ftype => Label fname -> (ftype : (store : s)) :-> (store : s) -- | Get storage field, preserving the storage itself on stack. stGetField :: forall store (fname :: Symbol) ftype (s :: [Type]). StoreHasField store fname ftype => Label fname -> (store : s) :-> (ftype : (store : s)) -- | Pick storage field. stToField :: forall store (fname :: Symbol) ftype (s :: [Type]). StoreHasField store fname ftype => Label fname -> (store : s) :-> (ftype : s) -- | Datatype containing the full implementation of StoreHasField -- typeclass. -- -- We use this grouping because in most cases the implementation will be -- chosen among the default ones, and initializing all methods at once is -- simpler and more consistent. (One can say that we are trying to -- emulate the DerivingVia extension.) data StoreFieldOps store (fname :: Symbol) ftype StoreFieldOps :: (forall (s :: [Type]). () => Label fname -> (store : s) :-> (ftype : s)) -> (forall (s :: [Type]). () => Label fname -> (ftype : (store : s)) :-> (store : s)) -> StoreFieldOps store (fname :: Symbol) ftype [sopToField] :: StoreFieldOps store (fname :: Symbol) ftype -> forall (s :: [Type]). () => Label fname -> (store : s) :-> (ftype : s) [sopSetField] :: StoreFieldOps store (fname :: Symbol) ftype -> forall (s :: [Type]). () => Label fname -> (ftype : (store : s)) :-> (store : s) -- | Provides operations on fields for storage. class StoreHasField store (fname :: Symbol) ftype | store fname -> ftype storeFieldOps :: StoreHasField store fname ftype => StoreFieldOps store fname ftype -- | Datatype containing the full implementation of StoreHasSubmap -- typeclass. -- -- We use this grouping because in most cases the implementation will be -- chosen among the default ones, and initializing all methods at once is -- simpler and more consistent. (One can say that we are trying to -- emulate the DerivingVia extension.) data StoreSubmapOps store (mname :: Symbol) key value StoreSubmapOps :: (forall (s :: [Type]). () => Label mname -> (key : (store : s)) :-> (Bool : s)) -> (forall (s :: [Type]). KnownValue value => Label mname -> (key : (store : s)) :-> (Maybe value : s)) -> (forall (s :: [Type]). () => Label mname -> (key : (Maybe value : (store : s))) :-> (store : s)) -> (forall (s :: [Type]). () => Label mname -> (key : (store : s)) :-> (store : s)) -> (forall (s :: [Type]). () => Label mname -> (key : (value : (store : s))) :-> (store : s)) -> StoreSubmapOps store (mname :: Symbol) key value [sopMem] :: StoreSubmapOps store (mname :: Symbol) key value -> forall (s :: [Type]). () => Label mname -> (key : (store : s)) :-> (Bool : s) [sopGet] :: StoreSubmapOps store (mname :: Symbol) key value -> forall (s :: [Type]). KnownValue value => Label mname -> (key : (store : s)) :-> (Maybe value : s) [sopUpdate] :: StoreSubmapOps store (mname :: Symbol) key value -> forall (s :: [Type]). () => Label mname -> (key : (Maybe value : (store : s))) :-> (store : s) [sopDelete] :: StoreSubmapOps store (mname :: Symbol) key value -> forall (s :: [Type]). () => Label mname -> (key : (store : s)) :-> (store : s) [sopInsert] :: StoreSubmapOps store (mname :: Symbol) key value -> forall (s :: [Type]). () => Label mname -> (key : (value : (store : s))) :-> (store : s) -- | Provides operations on submaps of storage. class StoreHasSubmap store (mname :: Symbol) key value | store mname -> key value storeSubmapOps :: StoreHasSubmap store mname key value => StoreSubmapOps store mname key value -- | Type synonym for a Lambda that can be used as an entrypoint type EntrypointLambda param store = Lambda (param, store) ([Operation], store) -- | Type synonym of a BigMap mapping MText (entrypoint -- names) to EntrypointLambda. -- -- This is useful when defining instances of StoreHasEntrypoint as -- a storage field containing one or more entrypoints (lambdas) of the -- same type. type EntrypointsField param store = BigMap MText EntrypointLambda param store -- | Datatype containing the full implementation of -- StoreHasEntrypoint typeclass. -- -- We use this grouping because in most cases the implementation will be -- chosen among the default ones, and initializing all methods at once is -- simpler and more consistent. (One can say that we are trying to -- emulate the DerivingVia extension.) data StoreEntrypointOps store (epName :: Symbol) epParam epStore StoreEntrypointOps :: (forall (s :: [Type]). () => Label epName -> (store : s) :-> (EntrypointLambda epParam epStore : s)) -> (forall (s :: [Type]). () => Label epName -> (EntrypointLambda epParam epStore : (store : s)) :-> (store : s)) -> (forall (s :: [Type]). () => Label epName -> (store : s) :-> (epStore : s)) -> (forall (s :: [Type]). () => Label epName -> (epStore : (store : s)) :-> (store : s)) -> StoreEntrypointOps store (epName :: Symbol) epParam epStore [sopToEpLambda] :: StoreEntrypointOps store (epName :: Symbol) epParam epStore -> forall (s :: [Type]). () => Label epName -> (store : s) :-> (EntrypointLambda epParam epStore : s) [sopSetEpLambda] :: StoreEntrypointOps store (epName :: Symbol) epParam epStore -> forall (s :: [Type]). () => Label epName -> (EntrypointLambda epParam epStore : (store : s)) :-> (store : s) [sopToEpStore] :: StoreEntrypointOps store (epName :: Symbol) epParam epStore -> forall (s :: [Type]). () => Label epName -> (store : s) :-> (epStore : s) [sopSetEpStore] :: StoreEntrypointOps store (epName :: Symbol) epParam epStore -> forall (s :: [Type]). () => Label epName -> (epStore : (store : s)) :-> (store : s) -- | Provides operations on stored entrypoints. -- -- store is the storage containing both the entrypoint -- epName (note: it has to be in a BigMap to take -- advantage of lazy evaluation) and the epStore field this -- operates on. class StoreHasEntrypoint store (epName :: Symbol) epParam epStore | store epName -> epParam epStore storeEpOps :: StoreHasEntrypoint store epName epParam epStore => StoreEntrypointOps store epName epParam epStore -- | Indicates a submap with given key and value types. data (k2 :: k) ~> (v :: k1) infix 9 ~> -- | Indicates a stored entrypoint with the given param and -- store types. data (param :: k) ::-> (store :: k1) infix 9 ::-> -- | Concise way to write down constraints with expected content of a -- storage. -- -- Use it like follows: -- --
-- type StorageConstraint store = StorageContains store -- [ "fieldInt" := Int -- , "fieldNat" := Nat -- , "epsToNat" := Int ::-> Nat -- , "balances" := Address ~> Int -- ] --type family StorageContains store (content :: [NamedField]) -- | Unwrap a constructor with the given name. Useful for sum types. unwrapUnsafe_ :: forall dt (name :: Symbol) (st :: [Type]). InstrUnwrapC dt name => Label name -> (dt : st) :-> (CtorOnlyField name dt : st) -- | Wrap entry in single-field constructor. Useful for sum types. wrapOne :: forall dt (name :: Symbol) (st :: [Type]). InstrWrapOneC dt name => Label name -> (CtorOnlyField name dt : st) :-> (dt : st) -- | Wrap entry in constructor. Useful for sum types. wrap_ :: forall dt (name :: Symbol) (st :: [Type]). InstrWrapC dt name => Label name -> AppendCtorField (GetCtorField dt name) st :-> (dt : st) -- | Lift an instruction to field constructor. fieldCtor :: forall (st :: [Type]) f. HasCallStack => (st :-> (f : st)) -> FieldConstructor st f -- | Decompose a complex object into its fields deconstruct :: forall dt (fields :: [Type]) (st :: [Type]). (InstrDeconstructC dt, KnownList fields, ToTs fields ~ ToTs (ConstructorFieldTypes dt)) => (dt : st) :-> (fields ++ st) -- | Construct an object from fields on the stack. constructStack :: forall dt (fields :: [Type]) (st :: [Type]). (InstrConstructC dt, ToTs fields ~ ToTs (ConstructorFieldTypes dt), KnownList fields) => (fields ++ st) :-> (dt : st) -- | Apply given modifier to a datatype field. modifyField :: forall dt (name :: Symbol) (st :: [Type]). (InstrGetFieldC dt name, InstrSetFieldC dt name) => Label name -> (forall (st0 :: [Type]). () => (GetFieldType dt name : st0) :-> (GetFieldType dt name : st0)) -> (dt : st) :-> (dt : st) -- | Like getField, but leaves field named. getFieldNamed :: forall dt (name :: Symbol) (st :: [Type]). InstrGetFieldC dt name => Label name -> (dt : st) :-> ((name :! GetFieldType dt name) : (dt : st)) -- | Extract a field of a datatype, leaving the original datatype on stack. getField :: forall dt (name :: Symbol) (st :: [Type]). InstrGetFieldC dt name => Label name -> (dt : st) :-> (GetFieldType dt name : (dt : st)) -- | Like toField, but leaves field named. toFieldNamed :: forall dt (name :: Symbol) (st :: [Type]). InstrGetFieldC dt name => Label name -> (dt : st) :-> ((name :! GetFieldType dt name) : st) -- | Extract a field of a datatype replacing the value of this datatype -- with the extracted field. -- -- For this and the following functions you have to specify field name -- which is either record name or name attached with (:!) -- operator. toField :: forall dt (name :: Symbol) (st :: [Type]). InstrGetFieldC dt name => Label name -> (dt : st) :-> (GetFieldType dt name : st) -- | Like HasField, but allows constrainting field type. type HasFieldOfType dt (fname :: Symbol) fieldTy = (HasField dt fname, GetFieldType dt fname ~ fieldTy) -- | A pair of field name and type. data NamedField NamedField :: Symbol -> Type -> NamedField type (n :: Symbol) := ty = 'NamedField n ty infixr 0 := -- | Shortcut for multiple HasFieldOfType constraints. type family HasFieldsOfType dt (fs :: [NamedField]) -- | Lorentz analogy of CaseClause, it works on plain Type -- types. data CaseClauseL (inp :: [Type]) (out :: [Type]) (param :: CaseClauseParam) [CaseClauseL] :: forall (x :: CtorField) (inp :: [Type]) (out :: [Type]) (ctor :: Symbol). (AppendCtorField x inp :-> out) -> CaseClauseL inp out ('CaseClauseParam ctor x) -- | Provides "case" arrow which works on different wrappers for clauses. class CaseArrow (name :: Symbol) body clause | clause -> name, clause -> body -- | Lift an instruction to case clause. -- -- You should write out constructor name corresponding to the clause -- explicitly. Prefix constructor name with "c" letter, otherwise your -- label will not be recognized by Haskell parser. Passing constructor -- name can be circumvented but doing so is not recomended as mentioning -- contructor name improves readability and allows avoiding some -- mistakes. (/->) :: CaseArrow name body clause => Label name -> body -> clause infixr 0 /-> type CaseTC dt (out :: [Type]) (inp :: [Type]) clauses = (InstrCaseC dt, RMap CaseClauses dt, RecFromTuple clauses, clauses ~ Rec CaseClauseL inp out CaseClauses dt) -- | Handlers for most common errors defined in Lorentz. baseErrorDocHandlers :: [NumericErrorDocHandler] -- | Handler for VoidResult. voidResultDocHandler :: NumericErrorDocHandler -- | Handler for all CustomErrors. customErrorDocHandler :: NumericErrorDocHandler -- | Extended version of applyErrorTagToErrorsDoc which accepts -- error handlers. -- -- In most cases that function should be enough for your purposes, but it -- uses a fixed set of base handlers which may be not enough in case when -- you define your own errors. In this case define and pass all the -- necessary handlers to this function. -- -- It fails with error if some of the errors used in the contract -- cannot be handled with given handlers. applyErrorTagToErrorsDocWith :: forall (inp :: [Type]) (out :: [Type]). HasCallStack => [NumericErrorDocHandler] -> ErrorTagMap -> (inp :-> out) -> inp :-> out -- | Modify documentation generated for given code so that all -- CustomError mention not their textual error tag rather -- respective numeric one from the given map. -- -- If some documented error is not present in the map, it remains -- unmodified. This function may fail with error if contract uses -- some uncommon errors, see applyErrorTagToErrorsDocWith for -- details. applyErrorTagToErrorsDoc :: forall (inp :: [Type]) (out :: [Type]). HasCallStack => ErrorTagMap -> (inp :-> out) -> inp :-> out -- | Adds a section which explains error tag mapping. data DDescribeErrorTagMap DDescribeErrorTagMap :: Text -> DDescribeErrorTagMap -- | Describes where the error tag map is defined in Haskell code. [detmSrcLoc] :: DDescribeErrorTagMap -> Text -- | Errors for NumericErrorDocHandler data NumericErrorDocHandlerError -- | Handler which changes documentation for one particular error type. data NumericErrorDocHandler -- | Some error with a numeric tag attached. data NumericErrorWrapper (numTag :: Nat) err voidResultTag :: MText -- | view type synonym as described in A1. data View a r -- | void type synonym as described in A1. data Void_ a b -- | Newtype over void result type used in tests to distinguish successful -- void result from other errors. -- -- Usage example: lExpectFailWith (== VoidResult roleMaster)` -- -- This error is special - it can contain arguments of different types -- depending on entrypoint which raises it. data VoidResult r -- | Implementation of castDummy for types composed from smaller -- types. It helps to ensure that all necessary constraints are requested -- in instance head. castDummyG :: (Generic a, Generic b, GCanCastTo (Rep a) (Rep b)) => Proxy a -> Proxy b -> () -- | Locally provide bidirectional CanCastTo instance. allowCheckedCoerce :: forall k1 k2 (a :: k1) (b :: k2). Dict (CanCastTo a b, CanCastTo b a) -- | Locally provide given CanCastTo instance. allowCheckedCoerceTo :: forall k1 k2 (b :: k1) (a :: k2). Dict (CanCastTo a b) -- | Pretends that the top item of the stack was coerced. checkedCoercing_ :: forall a b (s :: [Type]). Coercible_ a b => ((b : s) :-> (b : s)) -> (a : s) :-> (a : s) -- | Coerce between types which have an explicit permission for that in the -- face of CanCastTo constraint. checkedCoerce_ :: forall a b (s :: [Type]). Castable_ a b => (a : s) :-> (b : s) -- | Coercion in Haskell world which respects CanCastTo. checkedCoerce :: (CanCastTo a b, Coercible a b) => a -> b -- | Unpack named value. fromNamed :: forall (name :: Symbol) a (s :: [Type]). Label name -> (NamedF Identity a name : s) :-> (a : s) -- | Lift given value to a named value. toNamed :: forall (name :: Symbol) a (s :: [Type]). Label name -> (a : s) :-> (NamedF Identity a name : s) -- | Specialized version of coerce_ to unwrap a haskell newtype. coerceUnwrap :: forall a (s :: [Type]). Wrappable a => (a : s) :-> (Unwrappable a : s) -- | Specialized version of coerce_ to wrap into a haskell -- newtype. coerceWrap :: forall a (s :: [Type]). Wrappable a => (Unwrappable a : s) :-> (a : s) fakeCoercing :: forall (s1 :: [Type]) (s2 :: [Type]) (s1' :: [Type]) (s2' :: [Type]). (s1 :-> s2) -> s1' :-> s2' -- | Convert between two stacks via failing. fakeCoerce :: forall (s1 :: [Type]) (s2 :: [Type]). s1 :-> s2 gForcedCoerce_ :: forall k t (a :: k) (b :: k) (s :: [Type]). MichelsonCoercible (t a) (t b) => (t a : s) :-> (t b : s) -- | Convert between values of types that have the same representation. -- -- This function is not safe in a sense that this allows * breaking -- invariants of casted type (example: UStore from -- morley-upgradeable), or * may stop compile on code changes (example: -- coercion of pair to a datatype with two fields will break if new field -- is added). Still, produced Michelson code will always be valid. -- -- Prefer using one of more specific functions from this module. forcedCoerce_ :: forall a b (s :: [Type]). MichelsonCoercible a b => (a : s) :-> (b : s) -- | Coercion for Haskell world. -- -- We discourage using this function on Lorentz types, consider using -- coerce instead. One of the reasons forthat is that in Lorentz -- it's common to declare types as newtypes consisting of existing -- primitives, and forcedCoerce tends to ignore all phantom type -- variables of newtypes thus violating their invariants. forcedCoerce :: Coercible a b => a -> b -- | Whether two types have the same Michelson representation. type MichelsonCoercible a b = ToT a ~ ToT b -- | Explicitly allowed coercions. -- -- a CanCastTo b proclaims that a can be casted -- to b without violating any invariants of b. -- -- This relation is reflexive; it may be symmetric or not. It -- tends to be composable: casting complex types usually requires -- permission to cast their respective parts; for such types consider -- using castDummyG as implementation of the method of this -- typeclass. -- -- For cases when a cast from a to b requires some -- validation, consider rather making a dedicated function which performs -- the necessary checks and then calls forcedCoerce. class CanCastTo (a :: k) (b :: k1) -- | An optional method which helps passing -Wredundant-constraints check. -- Also, you can set specific implementation for it with specific sanity -- checks. castDummy :: CanCastTo a b => Proxy a -> Proxy b -> () -- | Coercion from a to b is permitted and safe. type Castable_ a b = (MichelsonCoercible a b, CanCastTo a b) -- | Coercions between a to b are permitted and safe. type Coercible_ a b = (MichelsonCoercible a b, CanCastTo a b, CanCastTo b a) -- | If you apply numeric error representation in your contract, -- errorToVal will stop working because it doesn't know about this -- transformation. This function takes this transformation into account. -- If a string is used as a tag, but it is not found in the passed map, -- we conservatively preserve that string (because this whole approach is -- rather a heuristic). errorToValNumeric :: IsError e => ErrorTagMap -> e -> (forall (t :: T). ErrorScope t => Value t -> r) -> r -- | If you apply numeric error representation in your contract, -- errorFromVal will stop working because it doesn't know about -- this transformation. This function takes this transformation into -- account. If a number is used as a tag, but it is not found in the -- passed map, we conservatively preserve that number (because this whole -- approach is rather a heuristic). errorFromValNumeric :: forall (t :: T) e. (KnownT t, IsError e) => ErrorTagMap -> Value t -> Either Text e -- | This function implements the simplest scenario of using this module's -- functionality: 1. Gather all error tags from a single instruction. 2. -- Turn them into error conversion map. 3. Apply this conversion. useNumericErrors :: forall (inp :: [Type]) (out :: [Type]). HasCallStack => (inp :-> out) -> (inp :-> out, ErrorTagMap) -- | Similar to applyErrorTagMap, but for case when you have -- excluded some tags from map via excludeErrorTags. Needed, -- because both excludeErrorTags and this function do not tolerate -- unknown errors in contract code (for your safety). applyErrorTagMapWithExclusions :: forall (inp :: [Type]) (out :: [Type]). HasCallStack => ErrorTagMap -> ErrorTagExclusions -> (inp :-> out) -> inp :-> out -- | For each typical FAILWITH that uses a string to represent error -- tag this function changes error tag to be a number using the supplied -- conversion map. It assumes that supplied map contains all such strings -- (and will error out if it does not). It will always be the case if you -- gather all error tags using gatherErrorTags and build -- ErrorTagMap from them using addNewErrorTags. applyErrorTagMap :: forall (inp :: [Type]) (out :: [Type]). HasCallStack => ErrorTagMap -> (inp :-> out) -> inp :-> out -- | Remove some error tags from map. This way you say to remain these -- string tags intact, while others will be converted to numbers when -- this map is applied. -- -- Note that later you have to apply this map using -- applyErrorTagMapWithExclusions, otherwise an error would be -- raised. excludeErrorTags :: HasCallStack => ErrorTagExclusions -> ErrorTagMap -> ErrorTagMap -- | Build ErrorTagMap from a set of textual tags. buildErrorTagMap :: HashSet MText -> ErrorTagMap -- | Add more error tags to an existing ErrorTagMap. It is useful -- when your contract consists of multiple parts (e. g. in case of -- contract upgrade), you have existing map for some part and want to add -- tags from another part to it. You can pass empty map as existing one -- if you just want to build ErrorTagMap from a set of textual -- tags. See buildErrorTagMap. addNewErrorTags :: ErrorTagMap -> HashSet MText -> ErrorTagMap -- | Find all textual error tags that are used in typical FAILWITH -- patterns within given instruction. Map them to natural numbers. gatherErrorTags :: forall (inp :: [Type]) (out :: [Type]). (inp :-> out) -> HashSet MText -- | This is a bidirectional map with correspondence between numeric and -- textual error tags. type ErrorTagMap = Bimap Natural MText -- | Tags excluded from map. type ErrorTagExclusions = HashSet MText -- | QuasiQuote that helps generating TypeHasDoc instance. -- -- Usage: -- --
-- [typeDoc| <type> <description> |] -- [typeDoc| Storage "This is storage description" |] ---- -- See this tutorial which includes this quasiquote. typeDoc :: QuasiQuoter -- | QuasiQuote that helps generating CustomErrorHasDoc instance. -- -- Usage: -- --
-- [errorDoc| <error-name> <error-type> <error-description> |] -- [errorDoc| "errorName" exception "Error description" |] ---- -- See this tutorial which includes this quasiquote. errorDoc :: QuasiQuoter -- | QuasiQuote that helps generating ParameterHasEntrypoints -- instance. -- -- Usage: -- --
-- [entrypointDoc| Parameter <parameter-type> <optional-root-annotation> |] -- [entrypointDoc| Parameter plain |] -- [entrypointDoc| Parameter plain "root"|] ---- -- See this tutorial which includes this quasiquote. entrypointDoc :: QuasiQuoter -- | Implementation of typeDocMdDescription (of TypeHasDoc -- typeclass) for Haskell types which sole purpose is to be error. typeDocMdDescriptionReferToError :: IsError e => Markdown -- | Whether given error class is about internal errors. -- -- Internal errors are not enlisted on per-entrypoint basis, only once -- for the entire contract. isInternalErrorClass :: ErrorClass -> Bool errorTagToText :: forall (tag :: Symbol). KnownSymbol tag => Text -- | Demote error tag to term level. errorTagToMText :: forall (tag :: Symbol). Label tag -> MText -- | Description of error representation in Haskell. customErrorDocHaskellRepGeneral :: forall (tag :: Symbol). (SingI (ToT (ErrorArg tag)), IsError (CustomError tag), TypeHasDoc (ErrorArg tag), CustomErrorHasDoc tag) => Text -> Proxy tag -> Markdown -- | Fail, providing a reference to the place in the code where this -- function is called. -- -- Like error in Haskell code, this instruction is for internal -- errors only. failUnexpected :: forall (s :: [Type]) (t :: [Type]). MText -> s :-> t -- | Fail with the given Haskell value. failUsing :: forall e (s :: [Type]) (t :: [Type]). IsError e => e -> s :-> t -- | Implementation of errorFromVal via IsoValue. isoErrorFromVal :: forall (t :: T) e. (Typeable t, Typeable (ToT e), IsoValue e) => Value t -> Either Text e -- | Implementation of errorToVal via IsoValue. isoErrorToVal :: (KnownError e, IsoValue e) => e -> (forall (t :: T). ErrorScope t => Value t -> r) -> r type ErrorScope (t :: T) = (Typeable t, ConstantScope t) -- | Haskell type representing error. class (Typeable e, ErrorHasDoc e) => IsError e -- | Converts a Haskell error into Value representation. errorToVal :: IsError e => e -> (forall (t :: T). ErrorScope t => Value t -> r) -> r -- | Converts a Value into Haskell error. errorFromVal :: forall (t :: T). (IsError e, KnownT t) => Value t -> Either Text e -- | Constraints which we require in a particular instance. You are not -- oblidged to often instantiate this correctly, it is only useful for -- some utilities. type family ErrorRequirements e class Typeable e => ErrorHasDoc e where { -- | Constraints which we require in a particular instance. You are not -- oblidged to often instantiate this correctly, it is only useful for -- some utilities. type family ErrorRequirements e; type ErrorRequirements e = (); } -- | Name of error as it appears in the corresponding section title. errorDocName :: ErrorHasDoc e => Text -- | What should happen for this error to be raised. errorDocMdCause :: ErrorHasDoc e => Markdown -- | Brief version of errorDocMdCause. -- -- This will appear along with the error when mentioned in entrypoint -- description. By default, the first sentence of the full description is -- used. errorDocMdCauseInEntrypoint :: ErrorHasDoc e => Markdown -- | How this error is represented in Haskell. errorDocHaskellRep :: ErrorHasDoc e => Markdown -- | Error class. errorDocClass :: ErrorHasDoc e => ErrorClass -- | Which definitions documentation for this error mentions. errorDocDependencies :: ErrorHasDoc e => [SomeDocDefinitionItem] -- | Captured constraints which we require in a particular instance. This -- is a way to encode a bidirectional instance in the nowaday Haskell, -- for class MyConstraint => ErrorHasDoc MyType instance it -- lets deducing MyConstraint by ErrorHasDoc MyType. -- -- You are not oblidged to always instantiate, it is only useful for some -- utilities which otherwise would not compile. errorDocRequirements :: ErrorHasDoc e => Dict (ErrorRequirements e) -- | Use this type as replacement for () when you really -- want to leave error cause unspecified. data UnspecifiedError UnspecifiedError :: UnspecifiedError -- | Type wrapper for an IsError. data SomeError SomeError :: e -> SomeError -- | Declares a custom error, defining error name - error argument -- relation. -- -- If your error is supposed to carry no argument, then provide -- (). -- -- Note that this relation is defined globally rather than on -- per-contract basis, so define errors accordingly. If your error has -- argument specific to your contract, call it such that error name -- reflects its belonging to this contract. -- -- This is the basic [error format]. type family ErrorArg (tag :: Symbol) -- | Material custom error. -- -- Use this in pattern matches against error (e.g. in tests). data CustomError (tag :: Symbol) CustomError :: Label tag -> ErrorArg tag -> CustomError (tag :: Symbol) [ceTag] :: CustomError (tag :: Symbol) -> Label tag [ceArg] :: CustomError (tag :: Symbol) -> ErrorArg tag type RequireNoArgError (tag :: Symbol) (msg :: ErrorMessage) = (TypeErrorUnless ErrorArg tag == () msg, msg ~ 'Text "Expected no-arg error, but given error requires argument of type " :<>: 'ShowType ErrorArg tag) -- | Error class on how the error should be handled by the client. data ErrorClass -- | Normal expected error. Examples: "insufficient balance", "wallet does -- not exist". ErrClassActionException :: ErrorClass -- | Invalid argument passed to entrypoint. Examples: your entrypoint -- accepts an enum represented as nat, and unknown value is -- provided. This includes more complex cases which involve multiple -- entrypoints. E.g. API provides iterator interface, middleware should -- care about using it hiding complex details and exposing a simpler API -- to user; then an attempt to request non-existing element would also -- correspond to an error from this class. ErrClassBadArgument :: ErrorClass -- | Unexpected error. Most likely it means that there is a bug in the -- contract or the contract has been deployed incorrectly. ErrClassContractInternal :: ErrorClass -- | It's possible to leave error class unspecified. ErrClassUnknown :: ErrorClass class (KnownSymbol tag, TypeHasDoc ErrorArg tag, IsError CustomError tag) => CustomErrorHasDoc (tag :: Symbol) -- | What should happen for this error to be raised. customErrDocMdCause :: CustomErrorHasDoc tag => Markdown -- | Brief version of customErrDocMdCause. This will appear along -- with the error when mentioned in entrypoint description. -- -- By default, the first sentence of the full description is used. customErrDocMdCauseInEntrypoint :: CustomErrorHasDoc tag => Markdown -- | Error class. -- -- By default this returns "unknown error" class; though you should -- provide explicit implementation in order to avoid a warning. customErrClass :: CustomErrorHasDoc tag => ErrorClass -- | Clarification of error argument meaning. -- -- Provide when it's not obvious, e.g. argument is not named with -- :!. -- -- NOTE: This should not be an entire sentence, rather just the -- semantic backbone. -- -- Bad: * Error argument stands for the previous value of -- approval. -- -- Good: * the previous value of approval * pair, first -- argument of which is one thing, and the second is another customErrArgumentSemantics :: CustomErrorHasDoc tag => Maybe Markdown -- | Mentions that contract uses given error. data DError [DError] :: forall e. ErrorHasDoc e => Proxy e -> DError -- | Documentation for custom errors. -- -- Mentions that entrypoint throws given error. data DThrows [DThrows] :: forall e. ErrorHasDoc e => Proxy e -> DThrows -- | Remove element with the given type from the stack. dropT :: forall a (inp :: [Type]) (dinp :: [Type]) (dout :: [Type]) (out :: [Type]). (DipT inp a inp dinp dout out, dinp ~ (a : dout)) => inp :-> out -- | Dip repeatedly until element of the given type is on top of the stack. -- -- If stack contains multiple entries of this type, compile error is -- raised. dipT :: forall a (inp :: [Type]) (dinp :: [Type]) (dout :: [Type]) (out :: [Type]). DipT inp a inp dinp dout out => (dinp :-> dout) -> inp :-> out -- | Duplicate an element of stack referring it by type. -- -- If stack contains multiple entries of this type, compile error is -- raised. dupT :: forall a (st :: [Type]). DupT st a st => st :-> (a : st) class NonZero t -- | Similar to valueToScriptExpr, but for values encoded as -- Expressions. This is only used in tests. expressionToScriptExpr :: Expression -> ByteString -- | This function transforms Lorentz values into script_expr. -- -- script_expr is used in RPC as an argument in entrypoint -- designed for getting value by key from the big_map in Babylon. In -- order to convert value to the script_expr we have to pack it, -- take blake2b hash and add specific expr prefix. Take a look -- at -- https://gitlab.com/tezos/tezos/blob/6e25ae8eb385d9975a30388c7a7aa2a9a65bf184/src/proto_005_PsBabyM1/lib_protocol/script_expr_hash.ml -- and -- https://gitlab.com/tezos/tezos/blob/6e25ae8eb385d9975a30388c7a7aa2a9a65bf184/src/proto_005_PsBabyM1/lib_protocol/contract_services.ml#L136 -- for more information. valueToScriptExpr :: NicePackedValue t => t -> ByteString lEncodeValue :: NicePrintedValue a => a -> ByteString lUnpackValue :: NiceUnpackedValue a => Packed a -> Either UnpackError a lPackValue :: NicePackedValue a => a -> Packed a lUnpackValueRaw :: NiceUnpackedValue a => ByteString -> Either UnpackError a lPackValueRaw :: NicePackedValue a => a -> ByteString -- | Evaluate hash in Haskell world. toHashHs :: forall (alg :: HashAlgorithmKind) bs. (BytesLike bs, KnownHashAlgorithm alg) => bs -> Hash alg bs -- | Sign data using Ed25519 curve. TODO [#456]: handle other methods, -- either all at once (if viable) or each one separately lSignEd22519 :: BytesLike a => SecretKey -> a -> TSignature a -- | Everything which is represented as bytes inside. class (KnownValue bs, ToT bs ~ ToT ByteString) => BytesLike bs toBytes :: BytesLike bs => bs -> ByteString -- | Represents a ByteString resulting from packing a value of type -- a. -- -- This is not guaranteed to keep some packed value, and -- unpack can fail. We do so because often we need to accept -- values of such type from user, and also because there is no simple way -- to check validity of packed data without performing full unpack. So -- this wrapper is rather a hint for users. newtype Packed a Packed :: ByteString -> Packed a [unPacked] :: Packed a -> ByteString -- | Represents a signature, where signed data has given type. -- -- Since we usually sign a packed data, a common pattern for this type is -- TSignature (Packed signedData). If you don't want to -- use Packed, use plain TSignature ByteString instead. newtype TSignature a TSignature :: Signature -> TSignature a [unTSignature] :: TSignature a -> Signature -- | Hash of type t evaluated from data of type a. newtype Hash (alg :: HashAlgorithmKind) a HashUnsafe :: ByteString -> Hash (alg :: HashAlgorithmKind) a [unHash] :: Hash (alg :: HashAlgorithmKind) a -> ByteString -- | Hash algorithm used in Tezos. class Typeable alg => KnownHashAlgorithm (alg :: HashAlgorithmKind) hashAlgorithmName :: KnownHashAlgorithm alg => Proxy alg -> Text computeHash :: KnownHashAlgorithm alg => ByteString -> ByteString toHash :: forall bs (s :: [Type]). (KnownHashAlgorithm alg, BytesLike bs) => (bs : s) :-> (Hash alg bs : s) -- | Documentation item for hash algorithms. data DHashAlgorithm data Sha256 (a :: HashAlgoTag) data Sha512 (a :: HashAlgoTag) data Blake2b (a :: HashAlgoTag) mkDEntrypointExample :: NiceParameter a => a -> DEntrypointExample -- | Leave only instructions related to documentation. -- -- This function is useful when your method executes a lambda coming from -- outside, but you know its properties and want to propagate its -- documentation to your contract code. cutLorentzNonDoc :: forall (inp :: [Type]) (out :: [Type]) (s :: [Type]). (inp :-> out) -> s :-> s renderLorentzDocWithGitRev :: forall (inp :: [Type]) (out :: [Type]). DGitRevision -> (inp :-> out) -> LText renderLorentzDoc :: forall (inp :: [Type]) (out :: [Type]). (inp :-> out) -> LText buildLorentzDocWithGitRev :: forall (inp :: [Type]) (out :: [Type]). DGitRevision -> (inp :-> out) -> ContractDoc buildLorentzDoc :: forall (inp :: [Type]) (out :: [Type]). (inp :-> out) -> ContractDoc -- | Modify the example value of an entrypoint data DEntrypointExample DEntrypointExample :: Value t -> DEntrypointExample -- | Pretty-print a Lorentz contract into Michelson code. printLorentzContract :: (NiceParameterFull cp, NiceStorage st) => Bool -> Contract cp st -> LText -- | Pretty-print a Haskell value as Michelson one. printLorentzValue :: NicePrintedValue v => Bool -> v -> LText -- | Lorentz version of analyzer. analyzeLorentz :: forall (inp :: [Type]) (out :: [Type]). (inp :-> out) -> AnalyzerRes -- | Like interpretLorentzInstr, but works on lambda rather than -- arbitrary instruction. interpretLorentzLambda :: (IsoValue inp, IsoValue out) => ContractEnv -> Lambda inp out -> inp -> Either MichelsonFailed out -- | Interpret a Lorentz instruction, for test purposes. Note that this -- does not run the optimizer. interpretLorentzInstr :: forall (inp :: [Type]) (out :: [Type]). (IsoValuesStack inp, IsoValuesStack out) => ContractEnv -> (inp :-> out) -> Rec Identity inp -> Either MichelsonFailed (Rec Identity out) -- | Compile a whole contract to Michelson. -- -- Note that compiled contract can be ill-typed in terms of Michelson -- code when some of the compilation options are used (e.g. when -- ccoDisableInitialCast is True, resulted contract can -- be ill-typed). However, compilation with -- defaultContractCompilationOptions should be valid. compileLorentzContract :: (NiceParameterFull cp, NiceStorage st) => Contract cp st -> Contract (ToT cp) (ToT st) -- | Compile contract with defaultCompilationOptions and -- cDisableInitialCast set to False. defaultContract :: ContractCode cp st -> Contract cp st -- | Compile Lorentz code, optionally running the optimizer, string and -- byte transformers. compileLorentzWithOptions :: forall (inp :: [Type]) (out :: [Type]). CompilationOptions -> (inp :-> out) -> Instr (ToTs inp) (ToTs out) -- | For use outside of Lorentz. Will use defaultCompilationOptions. compileLorentz :: forall (inp :: [Type]) (out :: [Type]). (inp :-> out) -> Instr (ToTs inp) (ToTs out) -- | Runs Michelson optimizer with default config and does not touch -- strings and bytes. defaultCompilationOptions :: CompilationOptions -- | Options to control Lorentz to Michelson compilation. data CompilationOptions CompilationOptions :: Maybe OptimizerConf -> (Bool, MText -> MText) -> (Bool, ByteString -> ByteString) -> CompilationOptions -- | Config for Michelson optimizer. [coOptimizerConf] :: CompilationOptions -> Maybe OptimizerConf -- | Function to transform strings with. See -- transformStringsLorentz. [coStringTransformer] :: CompilationOptions -> (Bool, MText -> MText) -- | Function to transform byte strings with. See -- transformBytesLorentz. [coBytesTransformer] :: CompilationOptions -> (Bool, ByteString -> ByteString) -- | Wrap parameter into this to locally assign a way to derive entrypoints -- for it. newtype ParameterWrapper deriv cp ParameterWrapper :: cp -> ParameterWrapper deriv cp [unParameterWraper] :: ParameterWrapper deriv cp -> cp type family Unwrappable s -- | Wrappable is similar to lens Wrapped class without the -- method. It provides type family that is mainly used as constraint when -- unwrapping Lorentz instruction into a Haskell newtype and vice versa. class ToT s ~ ToT Unwrappable s => Wrappable s where { type family Unwrappable s; type Unwrappable s = GUnwrappable Rep s; } type family ArithResHs aop n m -- | Lifted ArithOp. class (ArithOp aop ToT n ToT m, NiceComparable n, NiceComparable m, ToT ArithResHs aop n m ~ ArithRes aop ToT n ToT m) => ArithOpHs aop n m where { type family ArithResHs aop n m; } type family UnaryArithResHs aop n -- | Lifted UnaryArithOp. class (UnaryArithOp aop ToT n, NiceComparable n, ToT UnaryArithResHs aop n ~ UnaryArithRes aop ToT n) => UnaryArithOpHs aop n where { type family UnaryArithResHs aop n; } -- | Implementation of ParameterHasEntrypoints which fits for case -- when your contract exposes multiple entrypoints via having sum type as -- its parameter. -- -- In particular, each constructor would produce a homonymous entrypoint -- with argument type equal to type of constructor field (each -- constructor should have only one field). Constructor called -- Default will designate the default entrypoint. data EpdPlain -- | Extension of EpdPlain on parameters being defined as several -- nested datatypes. -- -- In particular, this will traverse sum types recursively, stopping at -- Michelson primitives (like Natural) and constructors with -- number of fields different from one. -- -- It does not assign names to intermediate nodes of Or tree, only -- to the very leaves. -- -- If some entrypoint arguments have custom IsoValue instance, -- this derivation way will not work. As a workaround, you can wrap your -- argument into some primitive (e.g. :!). data EpdRecursive -- | Extension of EpdPlain on parameters being defined as several -- nested datatypes. -- -- In particular, it will traverse the immediate sum type, and require -- another ParameterHasEntrypoints for the inner complex -- datatypes. Only those inner types are considered which are the only -- fields in their respective constructors. Inner types should not -- themselves declare default entrypoint, we enforce this for better -- modularity. Each top-level constructor will be treated as entrypoint -- even if it contains a complex datatype within, in such case that would -- be an entrypoint corresponding to intermediate node in or -- tree. -- -- Comparing to EpdRecursive this gives you more control over -- where and how entrypoints will be derived. data EpdDelegate -- | Extension of EpdPlain, EpdRecursive, and -- EpdDelegate which allow specifying root annotation for the -- parameters. data EpdWithRoot (r :: Symbol) (epd :: k) type List = [] -- | Provides Buildable instance that prints Lorentz value via -- Michelson's Value. -- -- Result won't be very pretty, but this avoids requiring Show or -- Buildable instances. newtype PrintAsValue a PrintAsValue :: a -> PrintAsValue a type family MemOpKeyHs c -- | Lifted MemOpKey. class (MemOp ToT c, ToT MemOpKeyHs c ~ MemOpKey ToT c) => MemOpHs c where { type family MemOpKeyHs c; } -- | A useful property which holds for reasonable MapOp instances. -- -- It's a separate thing from MapOpHs because it mentions -- b type parameter. type family IsoMapOpRes c b type family MapOpResHs c :: Type -> Type type family MapOpInpHs c -- | Lifted MapOp. class (MapOp ToT c, ToT MapOpInpHs c ~ MapOpInp ToT c, ToT MapOpResHs c () ~ MapOpRes ToT c ToT ()) => MapOpHs c where { type family MapOpInpHs c; type family MapOpResHs c :: Type -> Type; } type family IterOpElHs c -- | Lifted IterOp. class (IterOp ToT c, ToT IterOpElHs c ~ IterOpEl ToT c) => IterOpHs c where { type family IterOpElHs c; } -- | Lifted SizeOp. -- -- This could be just a constraint alias, but to avoid T types -- appearance in error messages we make a full type class with concrete -- instances. class SizeOp ToT c => SizeOpHs c type family UpdOpParamsHs c type family UpdOpKeyHs c -- | Lifted UpdOp. class (UpdOp ToT c, ToT UpdOpKeyHs c ~ UpdOpKey ToT c, ToT UpdOpParamsHs c ~ UpdOpParams ToT c) => UpdOpHs c where { type family UpdOpKeyHs c; type family UpdOpParamsHs c; } type family GetOpValHs c type family GetOpKeyHs c -- | Lifted GetOp. class (GetOp ToT c, ToT GetOpKeyHs c ~ GetOpKey ToT c, ToT GetOpValHs c ~ GetOpVal ToT c) => GetOpHs c where { type family GetOpKeyHs c; type family GetOpValHs c; } -- | Lifted ConcatOp. class ConcatOp ToT c => ConcatOpHs c -- | Lifted SliceOp. class SliceOp ToT c => SliceOpHs c type family EModOpResHs n m type family EDivOpResHs n m -- | Lifted EDivOp. class (EDivOp ToT n ToT m, NiceComparable n, NiceComparable m, ToT EDivOpResHs n m ~ EDivOpRes ToT n ToT m, ToT EModOpResHs n m ~ EModOpRes ToT n ToT m) => EDivOpHs n m where { type family EDivOpResHs n m; type family EModOpResHs n m; } -- | Fix the current type of the stack to be given one. -- --
-- >>> stackType @'[Natural] -- -- >>> stackType @(Integer : Natural : s) -- -- >>> stackType @'["balance" :! Integer, "toSpend" :! Integer, BigMap Address Integer] ---- -- Note that you can omit arbitrary parts of the type. -- --
-- >>> stackType @'["balance" :! Integer, "toSpend" :! _, BigMap _ _] --stackType :: forall (s :: [Type]). s :-> s -- | Test an invariant, fail if it does not hold. -- -- This won't be included into production contract and is executed only -- in tests. testAssert :: forall (out :: [Type]) (inp :: [Type]). (Typeable (ToTs out), HasCallStack) => Text -> PrintComment (ToTs inp) -> (inp :-> (Bool : out)) -> inp :-> inp -- | Print a comment. It will be visible in tests. -- --
-- >>> printComment "Hello world!" -- -- >>> printComment $ "On top of the stack I see " <> stackRef @0 --printComment :: forall (s :: [Type]). PrintComment (ToTs s) -> s :-> s -- | Include a value at given position on stack into comment produced by -- printComment. -- --
-- >>> stackRef @0 -- <includes the top of the stack> --stackRef :: forall (gn :: Nat) (st :: [T]) (n :: Peano). (n ~ ToPeano gn, SingI n, KnownPeano n, RequireLongerThan st n) => PrintComment st convertContractRef :: forall cp contract2 contract1. (ToContractRef cp contract1, FromContractRef cp contract2) => contract1 -> contract2 -- | Specification of callTAddress to call the default entrypoint. callingDefTAddress :: NiceParameterFull cp => TAddress cp -> ContractRef (GetDefaultEntrypointArg cp) -- | Turn TAddress to ContractRef in Haskell world. -- -- This is an analogy of address to contract convertion -- in Michelson world, thus you have to supply an entrypoint (or call the -- default one explicitly). callingTAddress :: forall cp (mname :: Maybe Symbol). NiceParameterFull cp => TAddress cp -> EntrypointRef mname -> ContractRef (GetEntrypointArgCustom cp mname) -- | Address which remembers the parameter type of the contract it refers -- to. -- -- It differs from Michelson's contract type because it cannot -- contain entrypoint, and it always refers to entire contract parameter -- even if this contract has explicit default entrypoint. newtype TAddress (p :: k) TAddress :: Address -> TAddress (p :: k) [unTAddress] :: TAddress (p :: k) -> Address -- | Address associated with value of contract arg type. -- -- Places where ContractRef can appear are now severely limited, -- this type gives you type-safety of ContractRef but still can be -- used everywhere. This type is not a full-featured one rather a helper; -- in particular, once pushing it on stack, you cannot return it back to -- Haskell world. -- -- Note that it refers to an entrypoint of the contract, not just the -- contract as a whole. In this sense this type differs from -- TAddress. -- -- Unlike with ContractRef, having this type you still cannot be -- sure that the referred contract exists and need to perform a lookup -- before calling it. newtype FutureContract arg FutureContract :: ContractRef arg -> FutureContract arg [unFutureContract] :: FutureContract arg -> ContractRef arg -- | Convert something to Address in Haskell world. -- -- Use this when you want to access state of the contract and are not -- interested in calling it. class ToAddress a toAddress :: ToAddress a => a -> Address -- | Convert something referring to a contract (not specific entrypoint) to -- TAddress in Haskell world. class ToTAddress cp a toTAddress :: ToTAddress cp a => a -> TAddress cp -- | Convert something to ContractRef in Haskell world. class ToContractRef cp contract toContractRef :: ToContractRef cp contract => contract -> ContractRef cp -- | Convert something from ContractAddr in Haskell world. class FromContractRef cp contract fromContractRef :: FromContractRef cp contract => ContractRef cp -> contract -- | Single entrypoint of a contract. -- -- Note that we cannot make it return [[Operation], store] -- because such entrypoint should've been followed by pair, and -- this is not possible if entrypoint implementation ends with -- failWith. type Entrypoint param store = '[param, store] :-> ContractOut store -- | Version of Entrypoint which accepts no argument. type Entrypoint_ store = '[store] :-> ContractOut store optimizeLorentz :: forall (inp :: [Type]) (out :: [Type]). (inp :-> out) -> inp :-> out optimizeLorentzWithConf :: forall (inp :: [Type]) (out :: [Type]). OptimizerConf -> (inp :-> out) -> inp :-> out -- | Lorentz version of transformBytes. transformBytesLorentz :: forall (inp :: [Type]) (out :: [Type]). Bool -> (ByteString -> ByteString) -> (inp :-> out) -> inp :-> out -- | Lorentz version of transformStrings. transformStringsLorentz :: forall (inp :: [Type]) (out :: [Type]). Bool -> (MText -> MText) -> (inp :-> out) -> inp :-> out -- | Parse textual representation of a Michelson value and turn it into -- corresponding Haskell value. -- -- Note: it won't work in some complex cases, e. g. if there is a lambda -- which uses an instruction which depends on current contract's type. -- Obviously it can not work, because we don't have any information about -- a contract to which this value belongs (there is no such contract at -- all). parseLorentzValue :: KnownValue v => Text -> Either ParseLorentzError v (#) :: forall (a :: [Type]) (b :: [Type]) (c :: [Type]). (a :-> b) -> (b :-> c) -> a :-> c infixl 8 # -- | Wrap Lorentz instruction with variable annotations, annots -- list has to be non-empty, otherwise this function raises an error. iWithVarAnnotations :: forall (inp :: [Type]) (out :: [Type]). HasCallStack => [Text] -> (inp :-> out) -> inp :-> out iForceNotFail :: forall (i :: [Type]) (o :: [Type]). (i :-> o) -> i :-> o iMapAnyCode :: forall (i1 :: [Type]) (i2 :: [Type]) (o :: [Type]). (forall (o' :: [T]). () => Instr (ToTs i1) o' -> Instr (ToTs i2) o') -> (i1 :-> o) -> i2 :-> o iNonFailingCode :: forall (inp :: [Type]) (out :: [Type]). HasCallStack => (inp :-> out) -> Instr (ToTs inp) (ToTs out) iAnyCode :: forall (inp :: [Type]) (out :: [Type]). (inp :-> out) -> Instr (ToTs inp) (ToTs out) iGenericIf :: forall (a :: [Type]) (b :: [Type]) (c :: [Type]) (s :: [Type]). (forall (s' :: [T]). () => Instr (ToTs a) s' -> Instr (ToTs b) s' -> Instr (ToTs c) s') -> (a :-> s) -> (b :-> s) -> c :-> s pattern I :: Instr (ToTs inp) (ToTs out) -> inp :-> out pattern FI :: (forall (out' :: [T]). () => Instr (ToTs inp) out') -> inp :-> out -- | Alias for instruction which hides inner types representation via -- T. newtype (inp :: [Type]) :-> (out :: [Type]) LorentzInstr :: RemFail Instr (ToTs inp) (ToTs out) -> (:->) (inp :: [Type]) (out :: [Type]) [unLorentzInstr] :: (:->) (inp :: [Type]) (out :: [Type]) -> RemFail Instr (ToTs inp) (ToTs out) infixr 1 :-> -- | Alias for :->, seems to make signatures more readable -- sometimes. -- -- Let's someday decide which one of these two should remain. type (%>) = (:->) infixr 1 %> type ContractOut st = '[([Operation], st)] type ContractCode cp st = '[(cp, st)] :-> ContractOut st data SomeContractCode [SomeContractCode] :: forall cp st. (NiceParameterFull cp, NiceStorage st) => ContractCode cp st -> SomeContractCode -- | An alias for :. -- -- We discourage its use as this hinders reading error messages (the -- compiler inserts unnecessary parentheses and indentation). type a & (b :: [Type]) = a : b infixr 2 & type Lambda i o = '[i] :-> '[o] -- | Applicable for wrappers over Lorentz code. class MapLorentzInstr instr -- | Modify all the code under given entity. mapLorentzInstr :: MapLorentzInstr instr => (forall (i :: [Type]) (o :: [Type]). () => (i :-> o) -> i :-> o) -> instr -> instr -- | Constraint applied to a whole parameter type. type NiceParameterFull cp = (Typeable cp, ParameterDeclaresEntrypoints cp) -- | Universal entrypoint calling. parameterEntrypointCallCustom :: forall cp (mname :: Maybe Symbol). ParameterDeclaresEntrypoints cp => EntrypointRef mname -> EntrypointCall cp (GetEntrypointArgCustom cp mname) eprName :: forall (mname :: Maybe Symbol). EntrypointRef mname -> EpName -- | Call root entrypoint safely. sepcCallRootChecked :: (NiceParameter cp, ForbidExplicitDefaultEntrypoint cp) => SomeEntrypointCall cp -- | Call the default entrypoint. parameterEntrypointCallDefault :: ParameterDeclaresEntrypoints cp => EntrypointCall cp (GetDefaultEntrypointArg cp) -- | Prepare call to given entrypoint. -- -- This does not treat calls to default entrypoint in a special way. To -- call default entrypoint properly use -- parameterEntrypointCallDefault. parameterEntrypointCall :: forall cp (name :: Symbol). ParameterDeclaresEntrypoints cp => Label name -> EntrypointCall cp (GetEntrypointArg cp name) -- | Derive annotations for given parameter. parameterEntrypointsToNotes :: ParameterDeclaresEntrypoints cp => ParamNotes (ToT cp) -- | Get entrypoint argument by name. type family EpdLookupEntrypoint (deriv :: k) cp :: Symbol -> Exp Maybe Type -- | Name and argument of each entrypoint. This may include intermediate -- ones, even root if necessary. -- -- Touching this type family is costly (O(N^2)), don't use it -- often. -- -- Note [order of entrypoints children]: If this contains entrypoints -- referring to indermediate nodes (not leaves) in or tree, then -- each such entrypoint should be mentioned eariler than all of its -- children. type family EpdAllEntrypoints (deriv :: k) cp :: [(Symbol, Type)] -- | Defines a generalized way to declare entrypoints for various parameter -- types. -- -- When defining instances of this typeclass, set concrete deriv -- argument and leave variable cp argument. Also keep in mind, -- that in presence of explicit default entrypoint, all other Or -- arms should be callable, though you can put this burden on user if -- very necessary. -- -- Methods of this typeclass aim to better type-safety when making up an -- implementation and they may be not too convenient to use; users should -- exploit their counterparts. class EntrypointsDerivation (deriv :: k) cp where { -- | Name and argument of each entrypoint. This may include intermediate -- ones, even root if necessary. -- -- Touching this type family is costly (O(N^2)), don't use it -- often. -- -- Note [order of entrypoints children]: If this contains entrypoints -- referring to indermediate nodes (not leaves) in or tree, then -- each such entrypoint should be mentioned eariler than all of its -- children. type family EpdAllEntrypoints (deriv :: k) cp :: [(Symbol, Type)]; -- | Get entrypoint argument by name. type family EpdLookupEntrypoint (deriv :: k) cp :: Symbol -> Exp Maybe Type; } -- | Construct parameter annotations corresponding to expected entrypoints -- set. -- -- This method is implementation detail, for actual notes construction -- use parameterEntrypointsToNotes. epdNotes :: EntrypointsDerivation deriv cp => (Notes (ToT cp), RootAnn) -- | Construct entrypoint caller. -- -- This does not treat calls to default entrypoint in a special way. -- -- This method is implementation detail, for actual entrypoint lookup use -- parameterEntrypointCall. epdCall :: forall (name :: Symbol). (EntrypointsDerivation deriv cp, ParameterScope (ToT cp)) => Label name -> EpConstructionRes (ToT cp) (Eval (EpdLookupEntrypoint deriv cp name)) -- | Description of how each of the entrypoints is constructed. epdDescs :: EntrypointsDerivation deriv cp => Rec EpCallingDesc (EpdAllEntrypoints deriv cp) -- | Ensure that all declared entrypoints are unique. type RequireAllUniqueEntrypoints cp = RequireAllUniqueEntrypoints' ParameterEntrypointsDerivation cp cp type family ParameterEntrypointsDerivation cp -- | Which entrypoints given parameter declares. -- -- Note that usually this function should not be used as constraint, use -- ParameterDeclaresEntrypoints for this purpose. class (EntrypointsDerivation ParameterEntrypointsDerivation cp cp, RequireAllUniqueEntrypoints cp) => ParameterHasEntrypoints cp where { type family ParameterEntrypointsDerivation cp; } -- | Parameter declares some entrypoints. -- -- This is a version of ParameterHasEntrypoints which we actually -- use in constraints. When given type is a sum type or newtype, we refer -- to ParameterHasEntrypoints instance, otherwise this instance is -- not necessary. type ParameterDeclaresEntrypoints cp = (If CanHaveEntrypoints cp ParameterHasEntrypoints cp (), NiceParameter cp, EntrypointsDerivation GetParameterEpDerivation cp cp) -- | Get all entrypoints declared for parameter. type family AllParameterEntrypoints cp :: [(Symbol, Type)] -- | Lookup for entrypoint type by name. -- -- Does not treat default entrypoints in a special way. type family LookupParameterEntrypoint cp :: Symbol -> Exp Maybe Type -- | Get type of entrypoint with given name, fail if not found. type GetEntrypointArg cp (name :: Symbol) = Eval LiftM2 FromMaybe :: Type -> Maybe Type -> Type -> Type TError 'Text "Entrypoint not found: " :<>: 'ShowType name :$$: 'Text "In contract parameter `" :<>: 'ShowType cp :<>: 'Text "`" :: Type -> Type LookupParameterEntrypoint cp name -- | Get type of entrypoint with given name, fail if not found. type GetDefaultEntrypointArg cp = Eval LiftM2 FromMaybe :: Type -> Maybe Type -> Type -> Type Pure cp LookupParameterEntrypoint cp DefaultEpName -- | Ensure that there is no explicit "default" entrypoint. type ForbidExplicitDefaultEntrypoint cp = Eval LiftM3 UnMaybe :: Exp Constraint -> Type -> Exp Constraint -> Maybe Type -> Constraint -> Type Pure Pure () TError 'Text "Parameter used here must have no explicit \"default\" entrypoint" :$$: 'Text "In parameter type `" :<>: 'ShowType cp :<>: 'Text "`" :: Type -> Exp Constraint -> Type LookupParameterEntrypoint cp DefaultEpName -- | Similar to ForbidExplicitDefaultEntrypoint, but in a version -- which the compiler can work with (and which produces errors confusing -- for users :/) type NoExplicitDefaultEntrypoint cp = Eval LookupParameterEntrypoint cp DefaultEpName ~ 'Nothing :: Maybe Type -- | Which entrypoint to call. -- -- We intentionally distinguish default and non-default cases because -- this makes API more details-agnostic. data EntrypointRef (mname :: Maybe Symbol) -- | Call the default entrypoint, or root if no explicit default is -- assigned. [CallDefault] :: EntrypointRef ('Nothing :: Maybe Symbol) -- | Call the given entrypoint; calling default is not treated specially. -- You have to provide entrypoint name via passing it as type argument. -- -- Unfortunatelly, here we cannot accept a label because in most cases -- our entrypoints begin from capital letter (being derived from -- constructor name), while labels must start from a lower-case letter, -- and there is no way to make a conversion at type-level. [Call] :: forall (name :: Symbol). NiceEntrypointName name => EntrypointRef ('Just name) -- | Universal entrypoint lookup. type family GetEntrypointArgCustom cp (mname :: Maybe Symbol) -- | When we call a Lorentz contract we should pass entrypoint name and -- corresponding argument. Ideally we want to statically check that -- parameter has entrypoint with given name and argument. Constraint -- defined by this type class holds for contract with parameter -- cp that have entrypoint matching name with type -- arg. -- -- In order to check this property statically, we need to know entrypoint -- name in compile time, EntrypointRef type serves this purpose. -- If entrypoint name is not known, one can use TrustEpName -- wrapper to take responsibility for presence of this entrypoint. -- -- If you want to call a function which has this constraint, you have two -- options: 1. Pass contract parameter cp using type -- application, pass EntrypointRef as a value and pass entrypoint -- argument. Type system will check that cp has an entrypoint -- with given reference and type. 2. Pass EpName wrapped into -- TrustEpName and entrypoint argument. In this case passing -- contract parameter is not necessary, you do not even have to know it. class HasEntrypointArg (cp :: k) name arg -- | Data returned by this method may look somewhat arbitrary. -- EpName is obviously needed because name can be -- EntrypointRef or TrustEpName. Dict is returned -- because in EntrypointRef case we get this evidence for free and -- don't want to use it. We seem to always need it anyway. useHasEntrypointArg :: HasEntrypointArg cp name arg => name -> (Dict (ParameterScope (ToT arg)), EpName) -- | HasEntrypointArg constraint specialized to default entrypoint. type HasDefEntrypointArg (cp :: k) defEpName defArg = (defEpName ~ EntrypointRef 'Nothing :: Maybe Symbol, HasEntrypointArg cp defEpName defArg) -- | This wrapper allows to pass untyped EpName and bypass checking -- that entrypoint with given name and type exists. newtype TrustEpName TrustEpName :: EpName -> TrustEpName -- | Checks that the given parameter consists of some specific entrypoint. -- Similar as HasEntrypointArg but ensures that the argument -- matches the following datatype. type HasEntrypointOfType param (con :: Symbol) exp = (GetEntrypointArgCustom param 'Just con ~ exp, ParameterDeclaresEntrypoints param) type (n :: Symbol) :> ty = 'NamedEp n ty infixr 0 :> -- | Check that the given entrypoint has some fields inside. This interface -- allows for an abstraction of contract parameter so that it requires -- some *minimal* specification, but not a concrete one. type family ParameterContainsEntrypoints param (fields :: [NamedEp]) -- | No entrypoints declared, parameter type will serve as argument type of -- the only existing entrypoint (default one). data EpdNone -- | A special type which wraps over a primitive type and states that it -- has entrypoints (one). -- -- Assuming that any type can have entrypoints makes use of Lorentz -- entrypoints too annoying, so for declaring entrypoints for not sum -- types we require an explicit wrapper. newtype ShouldHaveEntrypoints a ShouldHaveEntrypoints :: a -> ShouldHaveEntrypoints a [unHasEntrypoints] :: ShouldHaveEntrypoints a -> a nicePrintedValueEvi :: NicePrintedValue a :- PrintedValScope (ToT a) niceUnpackedValueEvi :: NiceUnpackedValue a :- UnpackedValScope (ToT a) nicePackedValueEvi :: NicePackedValue a :- PackedValScope (ToT a) niceConstantEvi :: NiceConstant a :- ConstantScope (ToT a) niceStorageEvi :: NiceStorage a :- StorageScope (ToT a) niceParameterEvi :: NiceParameter a :- ParameterScope (ToT a) -- | Gathers constraints, commonly required for values. class (IsoValue a, Typeable a) => KnownValue a -- | Ensure given type does not contain "operation". class (IsoValue a, ForbidOp ToT a) => NoOperation a class (IsoValue a, ForbidContract ToT a) => NoContractType a class (IsoValue a, ForbidBigMap ToT a) => NoBigMap a class (IsoValue a, HasNoNestedBigMaps ToT a) => CanHaveBigMap a -- | Constraint applied to any part of parameter type. -- -- Note that you don't usually apply this constraint to the whole -- parameter, consider using NiceParameterFull in such case. -- -- Using this type is justified e.g. when calling another contract, there -- you usually supply an entrypoint argument, not the whole parameter. type NiceParameter a = (KnownValue a, ProperParameterBetterErrors ToT a) type NiceStorage a = (HasAnnotation a, KnownValue a, ProperStorageBetterErrors ToT a) type NiceConstant a = (KnownValue a, ProperConstantBetterErrors ToT a) type NicePackedValue a = (KnownValue a, ProperPackedValBetterErrors ToT a) type NiceUnpackedValue a = (KnownValue a, ProperUnpackedValBetterErrors ToT a) type NiceFullPackedValue a = (NicePackedValue a, NiceUnpackedValue a) type NicePrintedValue a = (KnownValue a, ProperPrintedValBetterErrors ToT a) type NiceComparable n = (KnownValue n, Comparable ToT n) -- | This class defines the type and field annotations for a given type. -- Right now the type annotations come from names in a named field, and -- field annotations are generated from the record fields. class HasAnnotation a -- | A record is parameterized by a universe u, an interpretation -- f and a list of rows rs. The labels or indices of -- the record are given by inhabitants of the kind u; the type -- of values at any label r :: u is given by its interpretation -- f r :: *. data Rec (a :: u -> Type) (b :: [u]) [RNil] :: forall u (a :: u -> Type). Rec a ('[] :: [u]) [:&] :: forall u (a :: u -> Type) (r :: u) (rs :: [u]). !a r -> !Rec a rs -> Rec a (r : rs) infixr 7 :& -- | arg unwraps a named parameter with the specified name. One way -- to use it is to match on arguments with -XViewPatterns: -- --
-- fn (arg #t -> t) (arg #f -> f) = ... ---- -- This way, the names of parameters can be inferred from the patterns: -- no type signature for fn is required. In case a type -- signature for fn is provided, the parameters must come in the -- same order: -- --
-- fn :: "t" :! Integer -> "f" :! Integer -> ... -- fn (arg #t -> t) (arg #f -> f) = ... -- ok -- fn (arg #f -> f) (arg #t -> t) = ... -- does not typecheck --arg :: forall (name :: Symbol) a. Name name -> (name :! a) -> a -- | argF is similar to arg: it unwraps a named parameter -- with the specified name. The difference is that the result of -- argF is inside an arity wrapper, which is Identity for -- normal parameters and Maybe for optional parameters. argF :: forall (name :: Symbol) f a. Name name -> NamedF f a name -> f a -- | A variation of arg for optional arguments. Requires a default -- value to handle the case when the optional argument was omitted: -- --
-- fn (argDef #answer 42 -> ans) = ... ---- -- In case you want to get a value wrapped in Maybe instead, use -- argF or ArgF. argDef :: forall (name :: Symbol) a. Name name -> a -> (name :? a) -> a -- | Infix notation for the type of a named parameter. type (name :: Symbol) :! a = NamedF Identity a name -- | Infix notation for the type of an optional named parameter. type (name :: Symbol) :? a = NamedF Maybe a name -- | In this strategy the desired depths of contructors (in the type tree) -- and fields (in each constructor's tree) are provided manually and -- simply checked against the number of actual constructors and fields. withDepths :: [CstrDepth] -> GenericStrategy -- | Strategy to make right-balanced instances (both in constructors and -- fields). rightBalanced :: GenericStrategy -- | Strategy to make left-balanced instances (both in constructors and -- fields). leftBalanced :: GenericStrategy -- | Strategy to make fully right-leaning instances (both in constructors -- and fields). rightComb :: GenericStrategy -- | Strategy to make fully left-leaning instances (both in constructors -- and fields). leftComb :: GenericStrategy -- | Helper for making a constructor depth. -- -- Note that this is only intended to be more readable than directly -- using a tuple with withDepths and for the ability to be used in -- places where RebindableSyntax overrides the number literal -- resolution. cstr :: forall (n :: Nat). KnownNat n => [Natural] -> CstrDepth -- | Helper for making a field depth. -- -- Note that this is only intended to be more readable than directly -- using a tuple with withDepths and for the ability to be used in -- places where RebindableSyntax overrides the number literal -- resolution. fld :: forall (n :: Nat). KnownNat n => Natural customGeneric :: String -> GenericStrategy -> Q [Dec] -- | A piece of markdown document. -- -- This is opposed to Text type, which in turn is not supposed to -- contain markup elements. type Markdown = Builder -- | Proxy for a label type that includes the KnownSymbol constraint data Label (name :: Symbol) [Label] :: forall (name :: Symbol). KnownSymbol name => Label name -- | Entrypoint name. -- -- There are two properties we care about: -- --
-- >>> [mt|Some text|]
-- MTextUnsafe { unMText = "Some text" }
--
--
-- -- >>> formatTimestamp [timestampQuote| 2019-02-21T16:54:12.2344523Z |] -- "2019-02-21T16:54:12Z" ---- -- Inspired by 'time-quote' library. timestampQuote :: QuasiQuoter -- | Data type corresponding to address structure in Tezos. data Address mkUType :: forall (x :: T). SingI x => Notes x -> Type -- | Address with optional entrypoint name attached to it. TODO: come up -- with better name? data EpAddress EpAddress :: Address -> EpName -> EpAddress -- | Address itself [eaAddress] :: EpAddress -> Address -- | Entrypoint name (might be empty) [eaEntrypoint] :: EpAddress -> EpName -- | Keeps documentation gathered for some piece of contract code. -- -- Used for building documentation of a contract. data ContractDoc ContractDoc :: DocBlock -> DocBlock -> Set SomeDocDefinitionItem -> Set DocItemId -> ContractDoc -- | All inlined doc items. [cdContents] :: ContractDoc -> DocBlock -- | Definitions used in document. -- -- Usually you put some large and repetitive descriptions here. This -- differs from the document content in that it contains sections which -- are always at top-level, disregard the nesting. -- -- All doc items which define docItemId method go here, and only -- they. [cdDefinitions] :: ContractDoc -> DocBlock -- | We remember all already declared entries to avoid cyclic dependencies -- in documentation items discovery. [cdDefinitionsSet] :: ContractDoc -> Set SomeDocDefinitionItem -- | We remember all already used identifiers. (Documentation naturally -- should not declare multiple items with the same identifier because -- that would make references to the respective anchors ambiguous). [cdDefinitionIds] :: ContractDoc -> Set DocItemId -- | A part of documentation to be grouped. Essentially incapsulates -- DocBlock. newtype SubDoc SubDoc :: DocBlock -> SubDoc -- | Several doc items of the same type. data DocSection DocSection :: (NonEmpty $ DocElem d) -> DocSection -- | A doc item which we store, along with related information. data DocElem d DocElem :: d -> Maybe SubDoc -> DocElem d -- | Doc item itself. [deItem] :: DocElem d -> d -- | Subdocumentation, if given item is a group. [deSub] :: DocElem d -> Maybe SubDoc -- | Hides some documentation item which is put to "definitions" section. data SomeDocDefinitionItem [SomeDocDefinitionItem] :: forall d. (DocItem d, DocItemPlacement d ~ 'DocItemInDefinitions) => d -> SomeDocDefinitionItem -- | Hides some documentation item. data SomeDocItem [SomeDocItem] :: forall d. DocItem d => d -> SomeDocItem -- | How to render section name. data DocSectionNameStyle -- | Suitable for block name. DocSectionNameBig :: DocSectionNameStyle -- | Suitable for subsection title within block. DocSectionNameSmall :: DocSectionNameStyle data DocItemRef (p :: DocItemPlacementKind) (r :: DocItemReferencedKind) [DocItemRef] :: DocItemId -> DocItemRef 'DocItemInDefinitions 'True [DocItemRefInlined] :: DocItemId -> DocItemRef 'DocItemInlined 'True [DocItemNoRef] :: DocItemRef 'DocItemInlined 'False -- | Where do we place given doc item. data DocItemPlacementKind -- | Placed in the document content itself. DocItemInlined :: DocItemPlacementKind -- | Placed in dedicated definitions section; can later be referenced. DocItemInDefinitions :: DocItemPlacementKind -- | Position of all doc items of some type. newtype DocItemPos DocItemPos :: (Natural, Text) -> DocItemPos -- | Some unique identifier of a doc item. -- -- All doc items which should be refer-able need to have this identifier. newtype DocItemId DocItemId :: Text -> DocItemId -- | A piece of documentation describing one property of a thing, be it a -- name or description of a contract, or an error throwable by given -- endpoint. -- -- Items of the same type appear close to each other in a rendered -- documentation and form a section. -- -- Doc items are later injected into a contract code via a dedicated -- nop-like instruction. Normally doc items which belong to one section -- appear in resulting doc in the same order in which they appeared in -- the contract. -- -- While documentation framework grows, this typeclass acquires more and -- more methods for fine tuning of existing rendering logic because we -- don't want to break backward compatibility, hope one day we will make -- everything concise :( E.g. all rendering and reording stuff could be -- merged in one method, and we could have several template -- implementations for it which would allow user to specify only stuff -- relevant to his case. class (Typeable d, DOrd d) => DocItem d where { -- | Defines where given doc item should be put. There are two options: 1. -- Inline right here (default behaviour); 2. Put into definitions -- section. -- -- Note that we require all doc items with "in definitions" placement to -- have Eq and Ord instances which comply the following -- law: if two documentation items describe the same entity or property, -- they should be considered equal. type family DocItemPlacement d :: DocItemPlacementKind; type family DocItemReferenced d :: DocItemReferencedKind; type DocItemPlacement d = 'DocItemInlined; type DocItemReferenced d = 'False; } -- | Position of this item in the resulting documentation; the smaller the -- value, the higher the section with this element will be placed. If the -- position is the same as other doc items, they will be placed base on -- their name, alphabetically. -- -- Documentation structure is not necessarily flat. If some doc item -- consolidates a whole documentation block within it, this block will -- have its own placement of items independent from outer parts of the -- doc. docItemPos :: DocItem d => Natural -- | When multiple items of the same type belong to one section, how this -- section will be called. -- -- If not provided, section will contain just untitled content. docItemSectionName :: DocItem d => Maybe Text -- | Description of a section. -- -- Can be used to mention some common things about all elements of this -- section. Markdown syntax is permitted here. docItemSectionDescription :: DocItem d => Maybe Markdown -- | How to render section name. -- -- Takes effect only if section name is set. docItemSectionNameStyle :: DocItem d => DocSectionNameStyle -- | Defines a function which constructs an unique identifier of given doc -- item, if it has been decided to put the doc item into definitions -- section. -- -- Identifier should be unique both among doc items of the same type and -- items of other types. Thus, consider using "typeId-contentId" pattern. docItemRef :: DocItem d => d -> DocItemRef (DocItemPlacement d) (DocItemReferenced d) -- | Render given doc item to Markdown, preferably one line, optionally -- with header. -- -- Accepts the smallest allowed level of header. (Using smaller value -- than provided one will interfere with existing headers thus delivering -- mess). docItemToMarkdown :: DocItem d => HeaderLevel -> d -> Markdown -- | Render table of contents entry for given doc item to Markdown. docItemToToc :: DocItem d => HeaderLevel -> d -> Markdown -- | All doc items which this doc item refers to. -- -- They will automatically be put to definitions as soon as given doc -- item is detected. docItemDependencies :: DocItem d => d -> [SomeDocDefinitionItem] -- | This function accepts doc items put under the same section in the -- order in which they appeared in the contract and returns their new -- desired order. It's also fine to use this function for filtering or -- merging doc items. -- -- Default implementation * leaves inlined items as is; * for items put -- to definitions, lexicographically sorts them by their id. docItemsOrder :: DocItem d => [d] -> [d] -- | Defines where given doc item should be put. There are two options: 1. -- Inline right here (default behaviour); 2. Put into definitions -- section. -- -- Note that we require all doc items with "in definitions" placement to -- have Eq and Ord instances which comply the following -- law: if two documentation items describe the same entity or property, -- they should be considered equal. type family DocItemPlacement d :: DocItemPlacementKind type family DocItemReferenced d :: DocItemReferencedKind -- | Generate DToc entry anchor from docItemRef. mdTocFromRef :: (DocItem d, DocItemReferenced d ~ 'True) => HeaderLevel -> Markdown -> d -> Markdown -- | Get doc item position at term-level. docItemPosition :: DocItem d => DocItemPos -- | Make a reference to doc item in definitions. docDefinitionRef :: (DocItem d, DocItemPlacement d ~ 'DocItemInDefinitions) => Markdown -> d -> Markdown -- | Reference to the given section. -- -- Will return Nothing if sections of given doc item type are -- not assumed to be referred outside. docItemSectionRef :: DocItem di => Maybe Markdown -- | Render documentation for SubDoc. subDocToMarkdown :: HeaderLevel -> SubDoc -> Markdown -- | A hand-made anchor. data DAnchor DAnchor :: Anchor -> DAnchor -- | Comment in the doc (mostly used for licenses) data DComment DComment :: Text -> DComment -- | Repository settings for DGitRevision. newtype GitRepoSettings GitRepoSettings :: (Text -> Text) -> GitRepoSettings -- | By commit sha make up a url to that commit in remote repository. [grsMkGitRevision] :: GitRepoSettings -> Text -> Text data DGitRevision DGitRevisionKnown :: DGitRevisionInfo -> DGitRevision DGitRevisionUnknown :: DGitRevision -- | Description of something. data DDescription DDescription :: Markdown -> DDescription -- | A function which groups a piece of doc under one doc item. type DocGrouping = SubDoc -> SomeDocItem -- | Render given contract documentation to markdown document. contractDocToMarkdown :: ContractDoc -> LText morleyRepoSettings :: GitRepoSettings -- | Make DGitRevision. -- --
-- >>> :t $mkDGitRevision -- GitRepoSettings -> DGitRevision --mkDGitRevision :: ExpQ type Operation = Operation' Instr type Value = Value' Instr newtype BigMap k v BigMap :: Map k v -> BigMap k v [unBigMap] :: BigMap k v -> Map k v -- | Since Contract name is used to designate contract code, lets -- call analogy of TContract type as follows. -- -- Note that type argument always designates an argument of entrypoint. -- If a contract has explicit default entrypoint (and no root -- entrypoint), ContractRef referring to it can never have the -- entire parameter as its type argument. data ContractRef arg ContractRef :: Address -> SomeEntrypointCall arg -> ContractRef arg [crAddress] :: ContractRef arg -> Address [crEntrypoint] :: ContractRef arg -> SomeEntrypointCall arg type WellTypedIsoValue a = (WellTyped ToT a, IsoValue a) type SomeEntrypointCall arg = SomeEntrypointCallT ToT arg type EntrypointCall param arg = EntrypointCallT ToT param ToT arg -- | Isomorphism between Michelson values and plain Haskell types. -- -- Default implementation of this typeclass converts ADTs to Michelson -- "pair"s and "or"s. class WellTypedToT a => IsoValue a where { -- | Type function that converts a regular Haskell type into a T -- type. type family ToT a :: T; type ToT a = GValueType Rep a; } -- | Converts a Haskell structure into Value representation. toVal :: IsoValue a => a -> Value (ToT a) -- | Converts a Value into Haskell type. fromVal :: IsoValue a => Value (ToT a) -> a -- | Type function that converts a regular Haskell type into a T -- type. type family ToT a :: T -- | Replace type argument of ContractAddr with isomorphic one. coerceContractRef :: ToT a ~ ToT b => ContractRef a -> ContractRef b -- | Constraint for instrConstruct and gInstrConstructStack. type InstrConstructC dt = (GenericIsoValue dt, GInstrConstruct Rep dt) -- | Types of all fields in a datatype. type ConstructorFieldTypes dt = GFieldTypes Rep dt -- | Require this type to be homomorphic. class IsHomomorphic (a :: k) -- | Require two types to be built from the same type constructor. -- -- E.g. HaveCommonTypeCtor (Maybe Integer) (Maybe Natural) is -- defined, while HaveCmmonTypeCtor (Maybe Integer) [Integer] is -- not. class HaveCommonTypeCtor (a :: k) (b :: k1) -- | Doc element with description of a type. data DType [DType] :: forall a. TypeHasDoc a => Proxy a -> DType -- | Data hides some type implementing TypeHasDoc. data SomeTypeWithDoc [SomeTypeWithDoc] :: forall td. TypeHasDoc td => Proxy td -> SomeTypeWithDoc -- | Description for a Haskell type appearing in documentation. class (Typeable a, SingI TypeDocFieldDescriptions a, FieldDescriptionsValid TypeDocFieldDescriptions a a) => TypeHasDoc a where { -- | Description of constructors and fields of a. -- -- See FieldDescriptions documentation for an example of usage. -- -- Descriptions will be checked at compile time to make sure that only -- existing constructors and fields are referenced. -- -- For that check to work instance Generic a is required -- whenever TypeDocFieldDescriptions is not empty. -- -- For implementation of the check see FieldDescriptionsValid type -- family. type family TypeDocFieldDescriptions a :: FieldDescriptions; type TypeDocFieldDescriptions a = '[] :: [(Symbol, (Maybe Symbol, [(Symbol, Symbol)]))]; } -- | Name of type as it appears in definitions section. -- -- Each type must have its own unique name because it will be used in -- identifier for references. -- -- Default definition derives name from Generics. If it does not fit, -- consider defining this function manually. (We tried using Data -- for this, but it produces names including module names which is not do -- we want). typeDocName :: TypeHasDoc a => Proxy a -> Text -- | Explanation of a type. Markdown formatting is allowed. typeDocMdDescription :: TypeHasDoc a => Markdown -- | How reference to this type is rendered, in Markdown. -- -- Examples: -- --
-- ($) :: (a -> b) -> a -> b -- (<$>) :: Functor f => (a -> b) -> f a -> f b ---- -- Whereas $ is function application, <$> is function -- application lifted over a Functor. -- --
-- >>> show <$> Nothing -- Nothing -- -- >>> show <$> Just 3 -- Just "3" ---- -- Convert from an Either Int Int to an -- Either Int String using show: -- --
-- >>> show <$> Left 17 -- Left 17 -- -- >>> show <$> Right 17 -- Right "17" ---- -- Double each element of a list: -- --
-- >>> (*2) <$> [1,2,3] -- [2,4,6] ---- -- Apply even to the second element of a pair: -- --
-- >>> even <$> (2,2) -- (2,True) --(<$>) :: Functor f => (a -> b) -> f a -> f b infixl 4 <$> -- | Put new GenCode. iput :: GenCode inp out -> IndigoState inp out -- | The simplest IndigoState, it does not modify the stack, nor the -- produced code. nopState :: IndigoState inp inp -- | Assigns a variable to reference the element on top of the stack. assignTopVar :: KnownValue x => Var x -> IndigoState (x : inp) (x : inp) withObject :: forall a r. KnownValue a => DecomposedObjects -> Var a -> (Object a -> r) -> r withObjectState :: forall a inp out. KnownValue a => Var a -> (Object a -> IndigoState inp out) -> IndigoState inp out -- | Utility function to create IndigoState that need access to the -- current StackVars. withStackVars :: (StackVars inp -> IndigoState inp out) -> IndigoState inp out type DecomposedObjects = Map RefId SomeObject data GenCodeHooks GenCodeHooks :: (forall inp out. Text -> (inp :-> out) -> inp :-> out) -> (forall inp out. Text -> (inp :-> out) -> inp :-> out) -> (forall inp out. Text -> (inp :-> out) -> inp :-> out) -> GenCodeHooks [gchStmtHook] :: GenCodeHooks -> forall inp out. Text -> (inp :-> out) -> inp :-> out [gchAuxiliaryHook] :: GenCodeHooks -> forall inp out. Text -> (inp :-> out) -> inp :-> out [gchExprHook] :: GenCodeHooks -> forall inp out. Text -> (inp :-> out) -> inp :-> out emptyGenCodeHooks :: GenCodeHooks data MetaData inp MetaData :: StackVars inp -> DecomposedObjects -> GenCodeHooks -> MetaData inp [mdStack] :: MetaData inp -> StackVars inp [mdObjects] :: MetaData inp -> DecomposedObjects [mdHooks] :: MetaData inp -> GenCodeHooks stmtHook :: forall inp out any. MetaData any -> Text -> (inp :-> out) -> inp :-> out stmtHookState :: Text -> IndigoState inp out -> IndigoState inp out auxiliaryHook :: forall inp out any. MetaData any -> Text -> (inp :-> out) -> inp :-> out auxiliaryHookState :: Text -> IndigoState inp out -> IndigoState inp out exprHook :: forall inp out any. MetaData any -> Text -> (inp :-> out) -> inp :-> out exprHookState :: Text -> IndigoState inp out -> IndigoState inp out replStkMd :: MetaData inp -> StackVars inp1 -> MetaData inp1 alterStkMd :: MetaData inp -> (StackVars inp -> StackVars inp1) -> MetaData inp1 -- | pushRef version for MetaData pushRefMd :: KnownValue a => Var a -> MetaData inp -> MetaData (a : inp) -- | pushNoRef version for MetaData pushNoRefMd :: KnownValue a => MetaData inp -> MetaData (a : inp) -- | popNoRef version for MetaData popNoRefMd :: MetaData (a : inp) -> MetaData inp -- | Resulting state of IndigoM. data GenCode inp out GenCode :: ~StackVars out -> (inp :-> out) -> (out :-> inp) -> GenCode inp out -- | Stack of the symbolic interpreter. [gcStack] :: GenCode inp out -> ~StackVars out -- | Generated Lorentz code. [gcCode] :: GenCode inp out -> inp :-> out -- | Clearing Lorentz code. [gcClear] :: GenCode inp out -> out :-> inp -- | Produces the generated Lorentz code that cleans after itself, leaving -- the same stack as the input one cleanGenCode :: GenCode inp out -> inp :-> inp -- | Version of # which performs some optimizations immediately. -- -- In particular, this avoids glueing Nops. (##) :: (a :-> b) -> (b :-> c) -> a :-> c instance GHC.Base.Semigroup Indigo.Internal.State.GenCodeHooks instance GHC.Base.Monoid Indigo.Internal.State.GenCodeHooks -- | This module contains the logic to lookup Vars in a stack and -- the actions to manipulate it. -- -- For efficiency, actions are implemented using Lorentz macros. To do so -- every necessary constraint is checked at runtime. module Indigo.Internal.Lookup -- | Puts a copy of the value for the given Var on top of the stack varActionGet :: forall a stk. KnownValue a => RefId -> StackVars stk -> stk :-> (a : stk) -- | Sets the value for the given Var to the topmost value on the -- stack varActionSet :: forall a stk. KnownValue a => RefId -> StackVars stk -> (a : stk) :-> stk -- | Updates the value for the given Var with the topmost value on -- the stack using the given binary instruction. varActionUpdate :: forall a b stk. (KnownValue a, KnownValue b) => RefId -> StackVars stk -> ('[b, a] :-> '[a]) -> (b : stk) :-> stk -- | Given a stack with a list of Operations on its bottom, updates -- it by appending the Operation on the top. varActionOperation :: HasSideEffects => StackVars stk -> (Operation : stk) :-> stk rtake :: Sing n -> Rec any s -> Rec any (Take n s) rdrop :: Sing n -> Rec any s -> Rec any (Drop n s) instance Data.Type.Equality.TestEquality Indigo.Internal.Lookup.TVal -- | This module serves the purpose of listing hiding rules of -- Prelude that conflicts with Indigo exported functions. module Indigo.Prelude -- | Append two lists, i.e., -- --
-- [x1, ..., xm] ++ [y1, ..., yn] == [x1, ..., xm, y1, ..., yn] -- [x1, ..., xm] ++ [y1, ...] == [x1, ..., xm, y1, ...] ---- -- If the first list is not finite, the result is the first list. (++) :: [a] -> [a] -> [a] infixr 5 ++ -- | The value of seq a b is bottom if a is bottom, and -- otherwise equal to b. In other words, it evaluates the first -- argument a to weak head normal form (WHNF). seq is -- usually introduced to improve performance by avoiding unneeded -- laziness. -- -- A note on evaluation order: the expression seq a b does -- not guarantee that a will be evaluated before -- b. The only guarantee given by seq is that the both -- a and b will be evaluated before seq -- returns a value. In particular, this means that b may be -- evaluated before a. If you need to guarantee a specific order -- of evaluation, you must use the function pseq from the -- "parallel" package. seq :: a -> b -> b infixr 0 `seq` -- | O(n). filter, applied to a predicate and a list, returns -- the list of those elements that satisfy the predicate; i.e., -- --
-- filter p xs = [ x | x <- xs, p x] ---- --
-- >>> filter odd [1, 2, 3] -- [1,3] --filter :: (a -> Bool) -> [a] -> [a] -- | O(min(m,n)). zip takes two lists and returns a list of -- corresponding pairs. -- --
-- zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')] ---- -- If one input list is short, excess elements of the longer list are -- discarded: -- --
-- zip [1] ['a', 'b'] = [(1, 'a')] -- zip [1, 2] ['a'] = [(1, 'a')] ---- -- zip is right-lazy: -- --
-- zip [] _|_ = [] -- zip _|_ [] = _|_ ---- -- zip is capable of list fusion, but it is restricted to its -- first list argument and its resulting list. zip :: [a] -> [b] -> [(a, b)] -- | otherwise is defined as the value True. It helps to make -- guards more readable. eg. -- --
-- f x | x < 0 = ... -- | otherwise = ... --otherwise :: Bool -- | Application operator. This operator is redundant, since ordinary -- application (f x) means the same as (f $ x). -- However, $ has low, right-associative binding precedence, so it -- sometimes allows parentheses to be omitted; for example: -- --
-- f $ g $ h x = f (g (h x)) ---- -- It is also useful in higher-order situations, such as map -- ($ 0) xs, or zipWith ($) fs xs. -- -- Note that ($) is levity-polymorphic in its result -- type, so that foo $ True where foo :: Bool -> -- Int# is well-typed. ($) :: forall (r :: RuntimeRep) a (b :: TYPE r). (a -> b) -> a -> b infixr 0 $ -- | general coercion from integral types fromIntegral :: (Integral a, Num b) => a -> b -- | general coercion to fractional types realToFrac :: (Real a, Fractional b) => a -> b -- | Conditional failure of Alternative computations. Defined by -- --
-- guard True = pure () -- guard False = empty ---- --
-- >>> safeDiv 4 0 -- Nothing -- >>> safeDiv 4 2 -- Just 2 ---- -- A definition of safeDiv using guards, but not guard: -- --
-- safeDiv :: Int -> Int -> Maybe Int -- safeDiv x y | y /= 0 = Just (x `div` y) -- | otherwise = Nothing ---- -- A definition of safeDiv using guard and Monad -- do-notation: -- --
-- safeDiv :: Int -> Int -> Maybe Int -- safeDiv x y = do -- guard (y /= 0) -- return (x `div` y) --guard :: Alternative f => Bool -> f () -- | The join function is the conventional monad join operator. It -- is used to remove one level of monadic structure, projecting its bound -- argument into the outer level. -- --
-- atomically :: STM a -> IO a ---- -- is used to run STM transactions atomically. So, by specializing -- the types of atomically and join to -- --
-- atomically :: STM (IO b) -> IO (IO b) -- join :: IO (IO b) -> IO b ---- -- we can compose them as -- --
-- join . atomically :: STM (IO b) -> IO b ---- -- to run an STM transaction and the IO action it returns. join :: Monad m => m (m a) -> m a -- | The Bounded class is used to name the upper and lower limits of -- a type. Ord is not a superclass of Bounded since types -- that are not totally ordered may also have upper and lower bounds. -- -- The Bounded class may be derived for any enumeration type; -- minBound is the first constructor listed in the data -- declaration and maxBound is the last. Bounded may also -- be derived for single-constructor datatypes whose constituent types -- are in Bounded. class Bounded a minBound :: Bounded a => a maxBound :: Bounded a => a -- | Class Enum defines operations on sequentially ordered types. -- -- The enumFrom... methods are used in Haskell's translation of -- arithmetic sequences. -- -- Instances of Enum may be derived for any enumeration type -- (types whose constructors have no fields). The nullary constructors -- are assumed to be numbered left-to-right by fromEnum from -- 0 through n-1. See Chapter 10 of the Haskell -- Report for more details. -- -- For any type that is an instance of class Bounded as well as -- Enum, the following should hold: -- --
-- enumFrom x = enumFromTo x maxBound -- enumFromThen x y = enumFromThenTo x y bound -- where -- bound | fromEnum y >= fromEnum x = maxBound -- | otherwise = minBound --class Enum a -- | the successor of a value. For numeric types, succ adds 1. succ :: Enum a => a -> a -- | the predecessor of a value. For numeric types, pred subtracts -- 1. pred :: Enum a => a -> a -- | Convert from an Int. toEnum :: Enum a => Int -> a -- | Convert to an Int. It is implementation-dependent what -- fromEnum returns when applied to a value that is too large to -- fit in an Int. fromEnum :: Enum a => a -> Int -- | Used in Haskell's translation of [n..] with [n..] = -- enumFrom n, a possible implementation being enumFrom n = n : -- enumFrom (succ n). For example: -- --
enumFrom 4 :: [Integer] = [4,5,6,7,...]
enumFrom 6 :: [Int] = [6,7,8,9,...,maxBound :: -- Int]
enumFromThen 4 6 :: [Integer] = [4,6,8,10...]
enumFromThen 6 2 :: [Int] = [6,2,-2,-6,...,minBound :: -- Int]
enumFromTo 6 10 :: [Int] = [6,7,8,9,10]
enumFromTo 42 1 :: [Integer] = []
enumFromThenTo 4 2 -6 :: [Integer] = -- [4,2,0,-2,-4,-6]
enumFromThenTo 6 8 2 :: [Int] = []
-- (x `quot` y)*y + (x `rem` y) == x --rem :: Integral a => a -> a -> a -- | simultaneous quot and rem quotRem :: Integral a => a -> a -> (a, a) -- | simultaneous div and mod divMod :: Integral a => a -> a -> (a, a) -- | conversion to Integer toInteger :: Integral a => a -> Integer infixl 7 `quot` infixl 7 `rem` -- | The Monad class defines the basic operations over a -- monad, a concept from a branch of mathematics known as -- category theory. From the perspective of a Haskell programmer, -- however, it is best to think of a monad as an abstract datatype -- of actions. Haskell's do expressions provide a convenient -- syntax for writing monadic expressions. -- -- Instances of Monad should satisfy the following: -- --
-- abs x * signum x == x ---- -- For real numbers, the signum is either -1 (negative), -- 0 (zero) or 1 (positive). signum :: Num a => a -> a -- | The Ord class is used for totally ordered datatypes. -- -- Instances of Ord can be derived for any user-defined datatype -- whose constituent types are in Ord. The declared order of the -- constructors in the data declaration determines the ordering in -- derived Ord instances. The Ordering datatype allows a -- single comparison to determine the precise ordering of two objects. -- -- The Haskell Report defines no laws for Ord. However, -- <= is customarily expected to implement a non-strict partial -- order and have the following properties: -- --
-- infixr 5 :^: -- data Tree a = Leaf a | Tree a :^: Tree a ---- -- the derived instance of Read in Haskell 2010 is equivalent to -- --
-- instance (Read a) => Read (Tree a) where
--
-- readsPrec d r = readParen (d > app_prec)
-- (\r -> [(Leaf m,t) |
-- ("Leaf",s) <- lex r,
-- (m,t) <- readsPrec (app_prec+1) s]) r
--
-- ++ readParen (d > up_prec)
-- (\r -> [(u:^:v,w) |
-- (u,s) <- readsPrec (up_prec+1) r,
-- (":^:",t) <- lex s,
-- (v,w) <- readsPrec (up_prec+1) t]) r
--
-- where app_prec = 10
-- up_prec = 5
--
--
-- Note that right-associativity of :^: is unused.
--
-- The derived instance in GHC is equivalent to
--
-- -- instance (Read a) => Read (Tree a) where -- -- readPrec = parens $ (prec app_prec $ do -- Ident "Leaf" <- lexP -- m <- step readPrec -- return (Leaf m)) -- -- +++ (prec up_prec $ do -- u <- step readPrec -- Symbol ":^:" <- lexP -- v <- step readPrec -- return (u :^: v)) -- -- where app_prec = 10 -- up_prec = 5 -- -- readListPrec = readListPrecDefault ---- -- Why do both readsPrec and readPrec exist, and why does -- GHC opt to implement readPrec in derived Read instances -- instead of readsPrec? The reason is that readsPrec is -- based on the ReadS type, and although ReadS is mentioned -- in the Haskell 2010 Report, it is not a very efficient parser data -- structure. -- -- readPrec, on the other hand, is based on a much more efficient -- ReadPrec datatype (a.k.a "new-style parsers"), but its -- definition relies on the use of the RankNTypes language -- extension. Therefore, readPrec (and its cousin, -- readListPrec) are marked as GHC-only. Nevertheless, it is -- recommended to use readPrec instead of readsPrec -- whenever possible for the efficiency improvements it brings. -- -- As mentioned above, derived Read instances in GHC will -- implement readPrec instead of readsPrec. The default -- implementations of readsPrec (and its cousin, readList) -- will simply use readPrec under the hood. If you are writing a -- Read instance by hand, it is recommended to write it like so: -- --
-- instance Read T where -- readPrec = ... -- readListPrec = readListPrecDefault --class Read a class (Num a, Ord a) => Real a -- | the rational equivalent of its real argument with full precision toRational :: Real a => a -> Rational -- | Extracting components of fractions. class (Real a, Fractional a) => RealFrac a -- | The function properFraction takes a real fractional number -- x and returns a pair (n,f) such that x = -- n+f, and: -- --
-- infixr 5 :^: -- data Tree a = Leaf a | Tree a :^: Tree a ---- -- the derived instance of Show is equivalent to -- --
-- instance (Show a) => Show (Tree a) where -- -- showsPrec d (Leaf m) = showParen (d > app_prec) $ -- showString "Leaf " . showsPrec (app_prec+1) m -- where app_prec = 10 -- -- showsPrec d (u :^: v) = showParen (d > up_prec) $ -- showsPrec (up_prec+1) u . -- showString " :^: " . -- showsPrec (up_prec+1) v -- where up_prec = 5 ---- -- Note that right-associativity of :^: is ignored. For example, -- --
-- fail s >>= f = fail s ---- -- If your Monad is also MonadPlus, a popular definition is -- --
-- fail _ = mzero --class Monad m => MonadFail (m :: Type -> Type) fail :: MonadFail m => String -> m a -- | Class for string-like datastructures; used by the overloaded string -- extension (-XOverloadedStrings in GHC). class IsString a fromString :: IsString a => String -> a -- | A functor with application, providing operations to -- --
-- (<*>) = liftA2 id ---- --
-- liftA2 f x y = f <$> x <*> y ---- -- Further, any definition must satisfy the following: -- --
pure id <*> v = -- v
pure (.) <*> u -- <*> v <*> w = u <*> (v -- <*> w)
pure f <*> -- pure x = pure (f x)
u <*> pure y = -- pure ($ y) <*> u
-- forall x y. p (q x y) = f x . g y ---- -- it follows from the above that -- --
-- liftA2 p (liftA2 q u v) = liftA2 f u . liftA2 g v ---- -- If f is also a Monad, it should satisfy -- -- -- -- (which implies that pure and <*> satisfy the -- applicative functor laws). class Functor f => Applicative (f :: Type -> Type) -- | Lift a value. pure :: Applicative f => a -> f a -- | Sequential application. -- -- A few functors support an implementation of <*> that is -- more efficient than the default one. (<*>) :: Applicative f => f (a -> b) -> f a -> f b -- | Lift a binary function to actions. -- -- Some functors support an implementation of liftA2 that is more -- efficient than the default one. In particular, if fmap is an -- expensive operation, it is likely better to use liftA2 than to -- fmap over the structure and then use <*>. liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c -- | Sequence actions, discarding the value of the first argument. (*>) :: Applicative f => f a -> f b -> f b -- | Sequence actions, discarding the value of the second argument. (<*) :: Applicative f => f a -> f b -> f a infixl 4 <*> infixl 4 *> infixl 4 <* -- | Data structures that can be folded. -- -- For example, given a data type -- --
-- data Tree a = Empty | Leaf a | Node (Tree a) a (Tree a) ---- -- a suitable instance would be -- --
-- instance Foldable Tree where -- foldMap f Empty = mempty -- foldMap f (Leaf x) = f x -- foldMap f (Node l k r) = foldMap f l `mappend` f k `mappend` foldMap f r ---- -- This is suitable even for abstract types, as the monoid is assumed to -- satisfy the monoid laws. Alternatively, one could define -- foldr: -- --
-- instance Foldable Tree where -- foldr f z Empty = z -- foldr f z (Leaf x) = f x z -- foldr f z (Node l k r) = foldr f (f k (foldr f z r)) l ---- -- Foldable instances are expected to satisfy the following -- laws: -- --
-- foldr f z t = appEndo (foldMap (Endo . f) t ) z ---- --
-- foldl f z t = appEndo (getDual (foldMap (Dual . Endo . flip f) t)) z ---- --
-- fold = foldMap id ---- --
-- length = getSum . foldMap (Sum . const 1) ---- -- sum, product, maximum, and minimum -- should all be essentially equivalent to foldMap forms, such -- as -- --
-- sum = getSum . foldMap Sum ---- -- but may be less defined. -- -- If the type is also a Functor instance, it should satisfy -- --
-- foldMap f = fold . fmap f ---- -- which implies that -- --
-- foldMap f . fmap g = foldMap (f . g) --class Foldable (t :: Type -> Type) -- | Functors representing data structures that can be traversed from left -- to right. -- -- A definition of traverse must satisfy the following laws: -- --
-- t :: (Applicative f, Applicative g) => f a -> g a ---- -- preserving the Applicative operations, i.e. -- --
-- t (pure x) = pure x -- t (f <*> x) = t f <*> t x ---- -- and the identity functor Identity and composition functors -- Compose are from Data.Functor.Identity and -- Data.Functor.Compose. -- -- (The naturality law is implied by parametricity.) -- -- Instances are similar to Functor, e.g. given a data type -- --
-- data Tree a = Empty | Leaf a | Node (Tree a) a (Tree a) ---- -- a suitable instance would be -- --
-- instance Traversable Tree where -- traverse f Empty = pure Empty -- traverse f (Leaf x) = Leaf <$> f x -- traverse f (Node l k r) = Node <$> traverse f l <*> f k <*> traverse f r ---- -- This is suitable even for abstract types, as the laws for -- <*> imply a form of associativity. -- -- The superclass instances should satisfy the following: -- --
-- from . to ≡ id -- to . from ≡ id --class Generic a -- | This class gives the integer associated with a type-level natural. -- There are instances of the class for every concrete literal: 0, 1, 2, -- etc. class KnownNat (n :: Nat) class IsLabel (x :: Symbol) a fromLabel :: IsLabel x a => a -- | The class of semigroups (types with an associative binary operation). -- -- Instances should satisfy the following: -- -- class Semigroup a -- | Reduce a non-empty list with <> -- -- The default definition should be sufficient, but this can be -- overridden for efficiency. sconcat :: Semigroup a => NonEmpty a -> a -- | Repeat a value n times. -- -- Given that this works on a Semigroup it is allowed to fail if -- you request 0 or fewer repetitions, and the default definition will do -- so. -- -- By making this a member of the class, idempotent semigroups and -- monoids can upgrade this to execute in O(1) by picking -- stimes = stimesIdempotent or stimes = -- stimesIdempotentMonoid respectively. stimes :: (Semigroup a, Integral b) => b -> a -> a -- | The class of monoids (types with an associative binary operation that -- has an identity). Instances should satisfy the following: -- --
-- >>> 2^100 :: Natural -- 1267650600228229401496703205376 ---- -- Operations whose result would be negative throw -- (Underflow :: ArithException), -- --
-- >>> -1 :: Natural -- *** Exception: arithmetic underflow --data Natural -- | The Maybe type encapsulates an optional value. A value of type -- Maybe a either contains a value of type a -- (represented as Just a), or it is empty (represented -- as Nothing). Using Maybe is a good way to deal with -- errors or exceptional cases without resorting to drastic measures such -- as error. -- -- The Maybe type is also a monad. It is a simple kind of error -- monad, where all errors are represented by Nothing. A richer -- error monad can be built using the Either type. data Maybe a Nothing :: Maybe a Just :: a -> Maybe a data Ordering LT :: Ordering EQ :: Ordering GT :: Ordering -- | Rational numbers, with numerator and denominator of some -- Integral type. -- -- Note that Ratio's instances inherit the deficiencies from the -- type parameter's. For example, Ratio Natural's Num -- instance has similar problems to Natural's. data Ratio a (:%) :: !a -> !a -> Ratio a -- | Arbitrary-precision rational numbers, represented as a ratio of two -- Integer values. A rational number may be constructed using the -- % operator. type Rational = Ratio Integer -- | A value of type IO a is a computation which, when -- performed, does some I/O before returning a value of type a. -- -- There is really only one way to "perform" an I/O action: bind it to -- Main.main in your program. When your program is run, the I/O -- will be performed. It isn't possible to perform I/O from an arbitrary -- function, unless that function is itself in the IO monad and -- called at some point, directly or indirectly, from Main.main. -- -- IO is a monad, so IO actions can be combined using -- either the do-notation or the >> and >>= -- operations from the Monad class. data IO a -- | A Word is an unsigned integral type, with the same size as -- Int. data Word -- | 8-bit unsigned integer type data Word8 -- | 16-bit unsigned integer type data Word16 -- | 32-bit unsigned integer type data Word32 -- | 64-bit unsigned integer type data Word64 -- | A value of type Ptr a represents a pointer to an -- object, or an array of objects, which may be marshalled to or from -- Haskell values of type a. -- -- The type a will often be an instance of class Storable -- which provides the marshalling operations. However this is not -- essential, and you can provide your own operations to access the -- pointer. For example you might write small foreign functions to get or -- set the fields of a C struct. data Ptr a -- | A value of type FunPtr a is a pointer to a function -- callable from foreign code. The type a will normally be a -- foreign type, a function type with zero or more arguments where -- --
-- foreign import ccall "stdlib.h &free" -- p_free :: FunPtr (Ptr a -> IO ()) ---- -- or a pointer to a Haskell function created using a wrapper stub -- declared to produce a FunPtr of the correct type. For example: -- --
-- type Compare = Int -> Int -> Bool -- foreign import ccall "wrapper" -- mkCompare :: Compare -> IO (FunPtr Compare) ---- -- Calls to wrapper stubs like mkCompare allocate storage, which -- should be released with freeHaskellFunPtr when no longer -- required. -- -- To convert FunPtr values to corresponding Haskell functions, -- one can define a dynamic stub for the specific foreign type, -- e.g. -- --
-- type IntFunction = CInt -> IO () -- foreign import ccall "dynamic" -- mkFun :: FunPtr IntFunction -> IntFunction --data FunPtr a -- | The Either type represents values with two possibilities: a -- value of type Either a b is either Left -- a or Right b. -- -- The Either type is sometimes used to represent a value which is -- either correct or an error; by convention, the Left constructor -- is used to hold an error value and the Right constructor is -- used to hold a correct value (mnemonic: "right" also means "correct"). -- --
-- >>> let s = Left "foo" :: Either String Int -- -- >>> s -- Left "foo" -- -- >>> let n = Right 3 :: Either String Int -- -- >>> n -- Right 3 -- -- >>> :type s -- s :: Either String Int -- -- >>> :type n -- n :: Either String Int ---- -- The fmap from our Functor instance will ignore -- Left values, but will apply the supplied function to values -- contained in a Right: -- --
-- >>> let s = Left "foo" :: Either String Int -- -- >>> let n = Right 3 :: Either String Int -- -- >>> fmap (*2) s -- Left "foo" -- -- >>> fmap (*2) n -- Right 6 ---- -- The Monad instance for Either allows us to chain -- together multiple actions which may fail, and fail overall if any of -- the individual steps failed. First we'll write a function that can -- either parse an Int from a Char, or fail. -- --
-- >>> import Data.Char ( digitToInt, isDigit )
--
-- >>> :{
-- let parseEither :: Char -> Either String Int
-- parseEither c
-- | isDigit c = Right (digitToInt c)
-- | otherwise = Left "parse error"
--
-- >>> :}
--
--
-- The following should work, since both '1' and '2'
-- can be parsed as Ints.
--
--
-- >>> :{
-- let parseMultiple :: Either String Int
-- parseMultiple = do
-- x <- parseEither '1'
-- y <- parseEither '2'
-- return (x + y)
--
-- >>> :}
--
--
-- -- >>> parseMultiple -- Right 3 ---- -- But the following should fail overall, since the first operation where -- we attempt to parse 'm' as an Int will fail: -- --
-- >>> :{
-- let parseMultiple :: Either String Int
-- parseMultiple = do
-- x <- parseEither 'm'
-- y <- parseEither '2'
-- return (x + y)
--
-- >>> :}
--
--
-- -- >>> parseMultiple -- Left "parse error" --data Either a b Left :: a -> Either a b Right :: b -> Either a b -- | The kind of constraints, like Show a data Constraint -- | Comparison of type-level naturals, as a function. type family CmpNat (a :: Nat) (b :: Nat) :: Ordering -- | Coercible is a two-parameter class that has instances for -- types a and b if the compiler can infer that they -- have the same representation. This class does not have regular -- instances; instead they are created on-the-fly during type-checking. -- Trying to manually declare an instance of Coercible is an -- error. -- -- Nevertheless one can pretend that the following three kinds of -- instances exist. First, as a trivial base-case: -- --
-- instance Coercible a a ---- -- Furthermore, for every type constructor there is an instance that -- allows to coerce under the type constructor. For example, let -- D be a prototypical type constructor (data or -- newtype) with three type arguments, which have roles -- nominal, representational resp. phantom. -- Then there is an instance of the form -- --
-- instance Coercible b b' => Coercible (D a b c) (D a b' c') ---- -- Note that the nominal type arguments are equal, the -- representational type arguments can differ, but need to have -- a Coercible instance themself, and the phantom type -- arguments can be changed arbitrarily. -- -- The third kind of instance exists for every newtype NT = MkNT -- T and comes in two variants, namely -- --
-- instance Coercible a T => Coercible a NT ---- --
-- instance Coercible T b => Coercible NT b ---- -- This instance is only usable if the constructor MkNT is in -- scope. -- -- If, as a library author of a type constructor like Set a, you -- want to prevent a user of your module to write coerce :: Set T -- -> Set NT, you need to set the role of Set's type -- parameter to nominal, by writing -- --
-- type role Set nominal ---- -- For more details about this feature, please refer to Safe -- Coercions by Joachim Breitner, Richard A. Eisenberg, Simon Peyton -- Jones and Stephanie Weirich. class a ~R# b => Coercible (a :: k) (b :: k) -- | CallStacks are a lightweight method of obtaining a partial -- call-stack at any point in the program. -- -- A function can request its call-site with the HasCallStack -- constraint. For example, we can define -- --
-- putStrLnWithCallStack :: HasCallStack => String -> IO () ---- -- as a variant of putStrLn that will get its call-site and -- print it, along with the string given as argument. We can access the -- call-stack inside putStrLnWithCallStack with -- callStack. -- --
-- putStrLnWithCallStack :: HasCallStack => String -> IO () -- putStrLnWithCallStack msg = do -- putStrLn msg -- putStrLn (prettyCallStack callStack) ---- -- Thus, if we call putStrLnWithCallStack we will get a -- formatted call-stack alongside our string. -- --
-- >>> putStrLnWithCallStack "hello" -- hello -- CallStack (from HasCallStack): -- putStrLnWithCallStack, called at <interactive>:2:1 in interactive:Ghci1 ---- -- GHC solves HasCallStack constraints in three steps: -- --
-- id x = x --id :: a -> a -- | Case analysis for the Either type. If the value is -- Left a, apply the first function to a; if it -- is Right b, apply the second function to b. -- --
-- >>> let s = Left "foo" :: Either String Int -- -- >>> let n = Right 3 :: Either String Int -- -- >>> either length (*2) s -- 3 -- -- >>> either length (*2) n -- 6 --either :: (a -> c) -> (b -> c) -> Either a b -> c -- | See examples in Control.Monad.Reader. Note, the partially -- applied function type (->) r is a simple reader monad. See -- the instance declaration below. class Monad m => MonadReader r (m :: Type -> Type) | m -> r -- | Retrieves the monad environment. ask :: MonadReader r m => m r -- | Executes a computation in a modified environment. local :: MonadReader r m => (r -> r) -> m a -> m a -- | Retrieves a function of the current environment. reader :: MonadReader r m => (r -> a) -> m a -- | Minimal definition is either both of get and put or -- just state class Monad m => MonadState s (m :: Type -> Type) | m -> s -- | Replace the state inside the monad. put :: MonadState s m => s -> m () -- | Embed a simple state action into the monad. state :: MonadState s m => (s -> (a, s)) -> m a -- | A space-efficient representation of a Word8 vector, supporting -- many efficient operations. -- -- A ByteString contains 8-bit bytes, or by using the operations -- from Data.ByteString.Char8 it can be interpreted as containing -- 8-bit characters. data ByteString -- | An infix synonym for fmap. -- -- The name of this operator is an allusion to $. Note the -- similarities between their types: -- --
-- ($) :: (a -> b) -> a -> b -- (<$>) :: Functor f => (a -> b) -> f a -> f b ---- -- Whereas $ is function application, <$> is function -- application lifted over a Functor. -- --
-- >>> show <$> Nothing -- Nothing -- -- >>> show <$> Just 3 -- Just "3" ---- -- Convert from an Either Int Int to an -- Either Int String using show: -- --
-- >>> show <$> Left 17 -- Left 17 -- -- >>> show <$> Right 17 -- Right "17" ---- -- Double each element of a list: -- --
-- >>> (*2) <$> [1,2,3] -- [2,4,6] ---- -- Apply even to the second element of a pair: -- --
-- >>> even <$> (2,2) -- (2,True) --(<$>) :: Functor f => (a -> b) -> f a -> f b infixl 4 <$> -- | A String is a list of characters. String constants in Haskell -- are values of type String. type String = [Char] -- | The class of types that can be converted to a hash value. -- -- Minimal implementation: hashWithSalt. class Hashable a -- | Return a hash value for the argument, using the given salt. -- -- The general contract of hashWithSalt is: -- --
-- >>> const 42 "hello" -- 42 ---- --
-- >>> map (const 42) [0..3] -- [42,42,42,42] --const :: a -> b -> a -- | Function composition. (.) :: (b -> c) -> (a -> b) -> a -> c infixr 9 . -- | A map from keys to values. A map cannot contain duplicate keys; each -- key can map to at most one value. data HashMap k v -- | A Map from keys k to values a. -- -- The Semigroup operation for Map is union, which -- prefers values from the left operand. If m1 maps a key -- k to a value a1, and m2 maps the same key -- to a different value a2, then their union m1 <> -- m2 maps k to a1. data Map k a -- | A handle managing output to the Haskell program's standard output -- channel. stdout :: Handle -- | Haskell defines operations to read and write characters from and to -- files, represented by values of type Handle. Each value of -- this type is a handle: a record used by the Haskell run-time -- system to manage I/O with file system objects. A handle has at -- least the following properties: -- --
-- mzero >>= f = mzero -- v >> mzero = mzero ---- -- The default definition is -- --
-- mzero = empty --mzero :: MonadPlus m => m a -- | An associative operation. The default definition is -- --
-- mplus = (<|>) --mplus :: MonadPlus m => m a -> m a -> m a -- | Right-to-left composition of functors. The composition of applicative -- functors is always applicative, but the composition of monads is not -- always a monad. newtype Compose (f :: k -> Type) (g :: k1 -> k) (a :: k1) Compose :: f (g a) -> Compose (f :: k -> Type) (g :: k1 -> k) (a :: k1) [getCompose] :: Compose (f :: k -> Type) (g :: k1 -> k) (a :: k1) -> f (g a) infixr 9 `Compose` infixr 9 `Compose` -- | If Void is uninhabited then any Functor that holds only -- values of type Void is holding no values. vacuous :: Functor f => f Void -> f a -- | Since Void values logically don't exist, this witnesses the -- logical reasoning tool of "ex falso quodlibet". -- --
-- >>> let x :: Either Void Int; x = Right 5
--
-- >>> :{
-- case x of
-- Right r -> r
-- Left l -> absurd l
-- :}
-- 5
--
absurd :: Void -> a
-- | Uninhabited data type
data Void
-- | Repeat a value n times.
--
-- -- mtimesDefault n a = a <> a <> ... <> a -- using <> (n-1) times ---- -- Implemented using stimes and mempty. -- -- This is a suitable definition for an mtimes member of -- Monoid. mtimesDefault :: (Integral b, Monoid a) => b -> a -> a -- | A generalization of cycle to an arbitrary Semigroup. May -- fail to terminate for some values in some semigroups. cycle1 :: Semigroup m => m -> m -- | Provide a Semigroup for an arbitrary Monoid. -- -- NOTE: This is not needed anymore since Semigroup became -- a superclass of Monoid in base-4.11 and this newtype be -- deprecated at some point in the future. data WrappedMonoid m -- | Option is effectively Maybe with a better instance of -- Monoid, built off of an underlying Semigroup instead of -- an underlying Monoid. -- -- Ideally, this type would not exist at all and we would just fix the -- Monoid instance of Maybe. -- -- In GHC 8.4 and higher, the Monoid instance for Maybe has -- been corrected to lift a Semigroup instance instead of a -- Monoid instance. Consequently, this type is no longer useful. -- It will be marked deprecated in GHC 8.8 and removed in GHC 8.10. newtype Option a Option :: Maybe a -> Option a [getOption] :: Option a -> Maybe a -- | The sortWith function sorts a list of elements using the user -- supplied function to project something out of each element sortWith :: Ord b => (a -> b) -> [a] -> [a] -- | A bifunctor is a type constructor that takes two type arguments and is -- a functor in both arguments. That is, unlike with -- Functor, a type constructor such as Either does not need -- to be partially applied for a Bifunctor instance, and the -- methods in this class permit mapping functions over the Left -- value or the Right value, or both at the same time. -- -- Formally, the class Bifunctor represents a bifunctor from -- Hask -> Hask. -- -- Intuitively it is a bifunctor where both the first and second -- arguments are covariant. -- -- You can define a Bifunctor by either defining bimap or -- by defining both first and second. -- -- If you supply bimap, you should ensure that: -- --
-- bimap id id ≡ id ---- -- If you supply first and second, ensure: -- --
-- first id ≡ id -- second id ≡ id ---- -- If you supply both, you should also ensure: -- --
-- bimap f g ≡ first f . second g ---- -- These ensure by parametricity: -- --
-- bimap (f . g) (h . i) ≡ bimap f h . bimap g i -- first (f . g) ≡ first f . first g -- second (f . g) ≡ second f . second g --class Bifunctor (p :: Type -> Type -> Type) -- | Map over both arguments at the same time. -- --
-- bimap f g ≡ first f . second g ---- --
-- >>> bimap toUpper (+1) ('j', 3)
-- ('J',4)
--
--
-- -- >>> bimap toUpper (+1) (Left 'j') -- Left 'J' ---- --
-- >>> bimap toUpper (+1) (Right 3) -- Right 4 --bimap :: Bifunctor p => (a -> b) -> (c -> d) -> p a c -> p b d -- | Map covariantly over the first argument. -- --
-- first f ≡ bimap f id ---- --
-- >>> first toUpper ('j', 3)
-- ('J',3)
--
--
-- -- >>> first toUpper (Left 'j') -- Left 'J' --first :: Bifunctor p => (a -> b) -> p a c -> p b c -- | Map covariantly over the second argument. -- --
-- second ≡ bimap id ---- --
-- >>> second (+1) ('j', 3)
-- ('j',4)
--
--
-- -- >>> second (+1) (Right 3) -- Right 4 --second :: Bifunctor p => (b -> c) -> p a b -> p a c -- | Extract everything except the last element of the stream. init :: NonEmpty a -> [a] -- | Extract the last element of the stream. last :: NonEmpty a -> a -- | Extract the possibly-empty tail of the stream. tail :: NonEmpty a -> [a] -- | Extract the first element of the stream. head :: NonEmpty a -> a -- | nonEmpty efficiently turns a normal list into a NonEmpty -- stream, producing Nothing if the input is empty. nonEmpty :: [a] -> Maybe (NonEmpty a) -- | Get a string representation of the current execution stack state. showStackTrace :: IO (Maybe String) -- | Get a trace of the current execution stack state. -- -- Returns Nothing if stack trace support isn't available on -- host machine. getStackTrace :: IO (Maybe [Location]) -- | Monads in which IO computations may be embedded. Any monad -- built by applying a sequence of monad transformers to the IO -- monad will be an instance of this class. -- -- Instances should satisfy the following laws, which state that -- liftIO is a transformer of monads: -- -- class Monad m => MonadIO (m :: Type -> Type) -- | Lift a computation from the IO monad. liftIO :: MonadIO m => IO a -> m a -- | Direct MonadPlus equivalent of filter. -- --
-- filter = ( mfilter :: (a -> Bool) -> [a] -> [a] ) ---- -- An example using mfilter with the Maybe monad: -- --
-- >>> mfilter odd (Just 1) -- Just 1 -- >>> mfilter odd (Just 2) -- Nothing --mfilter :: MonadPlus m => (a -> Bool) -> m a -> m a -- | Strict version of <$>. (<$!>) :: Monad m => (a -> b) -> m a -> m b infixl 4 <$!> -- | Like replicateM, but discards the result. replicateM_ :: Applicative m => Int -> m a -> m () -- | replicateM n act performs the action n times, -- gathering the results. replicateM :: Applicative m => Int -> m a -> m [a] -- | Like foldM, but discards the result. foldM_ :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m () -- | The foldM function is analogous to foldl, except that -- its result is encapsulated in a monad. Note that foldM works -- from left-to-right over the list arguments. This could be an issue -- where (>>) and the `folded function' are not -- commutative. -- --
-- foldM f a1 [x1, x2, ..., xm] -- -- == -- -- do -- a2 <- f a1 x1 -- a3 <- f a2 x2 -- ... -- f am xm ---- -- If right-to-left evaluation is required, the input list should be -- reversed. -- -- Note: foldM is the same as foldlM foldM :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b -- | zipWithM_ is the extension of zipWithM which ignores the -- final result. zipWithM_ :: Applicative m => (a -> b -> m c) -> [a] -> [b] -> m () -- | The zipWithM function generalizes zipWith to arbitrary -- applicative functors. zipWithM :: Applicative m => (a -> b -> m c) -> [a] -> [b] -> m [c] -- | The mapAndUnzipM function maps its first argument over a list, -- returning the result as a pair of lists. This function is mainly used -- with complicated data structures or a state monad. mapAndUnzipM :: Applicative m => (a -> m (b, c)) -> [a] -> m ([b], [c]) -- | Repeat an action indefinitely. -- --
-- echoServer :: Socket -> IO () -- echoServer socket = forever $ do -- client <- accept socket -- forkFinally (echo client) (\_ -> hClose client) -- where -- echo :: Handle -> IO () -- echo client = forever $ -- hGetLine client >>= hPutStrLn client --forever :: Applicative f => f a -> f b -- | Right-to-left composition of Kleisli arrows. -- (>=>), with the arguments flipped. -- -- Note how this operator resembles function composition -- (.): -- --
-- (.) :: (b -> c) -> (a -> b) -> a -> c -- (<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c --(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c infixr 1 <=< -- | Left-to-right composition of Kleisli arrows. (>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c infixr 1 >=> -- | This generalizes the list-based filter function. filterM :: Applicative m => (a -> m Bool) -> [a] -> m [a] -- | This function may be used as a value for foldMap in a -- Foldable instance. -- --
-- foldMapDefault f ≡ getConst . traverse (Const . f) --foldMapDefault :: (Traversable t, Monoid m) => (a -> m) -> t a -> m -- | This function may be used as a value for fmap in a -- Functor instance, provided that traverse is defined. -- (Using fmapDefault with a Traversable instance defined -- only by sequenceA will result in infinite recursion.) -- --
-- fmapDefault f ≡ runIdentity . traverse (Identity . f) --fmapDefault :: Traversable t => (a -> b) -> t a -> t b -- | The mapAccumR function behaves like a combination of -- fmap and foldr; it applies a function to each element of -- a structure, passing an accumulating parameter from right to left, and -- returning a final value of this accumulator together with the new -- structure. mapAccumR :: Traversable t => (a -> b -> (a, c)) -> a -> t b -> (a, t c) -- | The mapAccumL function behaves like a combination of -- fmap and foldl; it applies a function to each element of -- a structure, passing an accumulating parameter from left to right, and -- returning a final value of this accumulator together with the new -- structure. mapAccumL :: Traversable t => (a -> b -> (a, c)) -> a -> t b -> (a, t c) -- | forM is mapM with its arguments flipped. For a version -- that ignores the results see forM_. forM :: (Traversable t, Monad m) => t a -> (a -> m b) -> m (t b) -- | One or none. optional :: Alternative f => f a -> f (Maybe a) -- | Lists, but with an Applicative functor based on zipping. newtype ZipList a ZipList :: [a] -> ZipList a [getZipList] :: ZipList a -> [a] -- | Fanout: send the input to both argument arrows and combine their -- output. -- -- The default definition may be overridden with a more efficient version -- if desired. (&&&) :: Arrow a => a b c -> a b c' -> a b (c, c') infixr 3 &&& -- | Identity functor and monad. (a non-strict monad) newtype Identity a Identity :: a -> Identity a [runIdentity] :: Identity a -> a -- | A handle managing output to the Haskell program's standard error -- channel. stderr :: Handle -- | A handle managing input from the Haskell program's standard input -- channel. stdin :: Handle -- | Perform some computation without adding new entries to the -- CallStack. withFrozenCallStack :: HasCallStack => (HasCallStack => a) -> a -- | Return the current CallStack. -- -- Does *not* include the call-site of callStack. callStack :: HasCallStack => CallStack -- | Write the supplied value into a TVar. writeTVar :: TVar a -> a -> STM () -- | Return the current value stored in a TVar. readTVar :: TVar a -> STM a -- | Create a new TVar holding a value supplied newTVar :: a -> STM (TVar a) -- | A monad supporting atomic memory transactions. data STM a -- | Shared memory locations that support atomic memory transactions. data TVar a -- | A mutable variable in the IO monad data IORef a -- | File and directory names are values of type String, whose -- precise meaning is operating system dependent. Files can be opened, -- yielding a handle which can then be used to operate on the contents of -- that file. type FilePath = String -- | Pretty print a CallStack. prettyCallStack :: CallStack -> String -- | Pretty print a SrcLoc. prettySrcLoc :: SrcLoc -> String -- | Any type that you wish to throw or catch as an exception must be an -- instance of the Exception class. The simplest case is a new -- exception type directly below the root: -- --
-- data MyException = ThisException | ThatException -- deriving Show -- -- instance Exception MyException ---- -- The default method definitions in the Exception class do what -- we need in this case. You can now throw and catch -- ThisException and ThatException as exceptions: -- --
-- *Main> throw ThisException `catch` \e -> putStrLn ("Caught " ++ show (e :: MyException))
-- Caught ThisException
--
--
-- In more complicated examples, you may wish to define a whole hierarchy
-- of exceptions:
--
-- -- --------------------------------------------------------------------- -- -- Make the root exception type for all the exceptions in a compiler -- -- data SomeCompilerException = forall e . Exception e => SomeCompilerException e -- -- instance Show SomeCompilerException where -- show (SomeCompilerException e) = show e -- -- instance Exception SomeCompilerException -- -- compilerExceptionToException :: Exception e => e -> SomeException -- compilerExceptionToException = toException . SomeCompilerException -- -- compilerExceptionFromException :: Exception e => SomeException -> Maybe e -- compilerExceptionFromException x = do -- SomeCompilerException a <- fromException x -- cast a -- -- --------------------------------------------------------------------- -- -- Make a subhierarchy for exceptions in the frontend of the compiler -- -- data SomeFrontendException = forall e . Exception e => SomeFrontendException e -- -- instance Show SomeFrontendException where -- show (SomeFrontendException e) = show e -- -- instance Exception SomeFrontendException where -- toException = compilerExceptionToException -- fromException = compilerExceptionFromException -- -- frontendExceptionToException :: Exception e => e -> SomeException -- frontendExceptionToException = toException . SomeFrontendException -- -- frontendExceptionFromException :: Exception e => SomeException -> Maybe e -- frontendExceptionFromException x = do -- SomeFrontendException a <- fromException x -- cast a -- -- --------------------------------------------------------------------- -- -- Make an exception type for a particular frontend compiler exception -- -- data MismatchedParentheses = MismatchedParentheses -- deriving Show -- -- instance Exception MismatchedParentheses where -- toException = frontendExceptionToException -- fromException = frontendExceptionFromException ---- -- We can now catch a MismatchedParentheses exception as -- MismatchedParentheses, SomeFrontendException or -- SomeCompilerException, but not other types, e.g. -- IOException: -- --
-- *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: MismatchedParentheses))
-- Caught MismatchedParentheses
-- *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: SomeFrontendException))
-- Caught MismatchedParentheses
-- *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: SomeCompilerException))
-- Caught MismatchedParentheses
-- *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: IOException))
-- *** Exception: MismatchedParentheses
--
class (Typeable e, Show e) => Exception e
toException :: Exception e => e -> SomeException
fromException :: Exception e => SomeException -> Maybe e
-- | Render this exception value in a human-friendly manner.
--
-- Default implementation: show.
displayException :: Exception e => e -> String
-- | The Const functor.
newtype Const a (b :: k)
Const :: a -> Const a (b :: k)
[getConst] :: Const a (b :: k) -> a
-- | The least element of a non-empty structure with respect to the given
-- comparison function.
minimumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a
-- | The largest element of a non-empty structure with respect to the given
-- comparison function.
maximumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a
-- | Map a function over all the elements of a container and concatenate
-- the resulting lists.
concatMap :: Foldable t => (a -> [b]) -> t a -> [b]
-- | Monadic fold over the elements of a structure, associating to the
-- left, i.e. from left to right.
foldlM :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b
-- | Monadic fold over the elements of a structure, associating to the
-- right, i.e. from right to left.
foldrM :: (Foldable t, Monad m) => (a -> b -> m b) -> b -> t a -> m b
-- | Maybe monoid returning the leftmost non-Nothing value.
--
-- First a is isomorphic to Alt Maybe
-- a, but precedes it historically.
--
-- -- >>> getFirst (First (Just "hello") <> First Nothing <> First (Just "world")) -- Just "hello" ---- -- Use of this type is discouraged. Note the following equivalence: -- --
-- Data.Monoid.First x === Maybe (Data.Semigroup.First x) ---- -- In addition to being equivalent in the structural sense, the two also -- have Monoid instances that behave the same. This type will be -- marked deprecated in GHC 8.8, and removed in GHC 8.10. Users are -- advised to use the variant from Data.Semigroup and wrap it in -- Maybe. newtype First a First :: Maybe a -> First a [getFirst] :: First a -> Maybe a -- | Maybe monoid returning the rightmost non-Nothing value. -- -- Last a is isomorphic to Dual (First -- a), and thus to Dual (Alt Maybe a) -- --
-- >>> getLast (Last (Just "hello") <> Last Nothing <> Last (Just "world")) -- Just "world" ---- -- Use of this type is discouraged. Note the following equivalence: -- --
-- Data.Monoid.Last x === Maybe (Data.Semigroup.Last x) ---- -- In addition to being equivalent in the structural sense, the two also -- have Monoid instances that behave the same. This type will be -- marked deprecated in GHC 8.8, and removed in GHC 8.10. Users are -- advised to use the variant from Data.Semigroup and wrap it in -- Maybe. newtype Last a Last :: Maybe a -> Last a [getLast] :: Last a -> Maybe a -- | This is a valid definition of stimes for a Monoid. -- -- Unlike the default definition of stimes, it is defined for 0 -- and so it should be preferred where possible. stimesMonoid :: (Integral b, Monoid a) => b -> a -> a -- | This is a valid definition of stimes for an idempotent -- Semigroup. -- -- When x <> x = x, this definition should be preferred, -- because it works in O(1) rather than O(log n). stimesIdempotent :: Integral b => b -> a -> a -- | The dual of a Monoid, obtained by swapping the arguments of -- mappend. -- --
-- >>> getDual (mappend (Dual "Hello") (Dual "World")) -- "WorldHello" --newtype Dual a Dual :: a -> Dual a [getDual] :: Dual a -> a -- | The monoid of endomorphisms under composition. -- --
-- >>> let computation = Endo ("Hello, " ++) <> Endo (++ "!")
--
-- >>> appEndo computation "Haskell"
-- "Hello, Haskell!"
--
newtype Endo a
Endo :: (a -> a) -> Endo a
[appEndo] :: Endo a -> a -> a
-- | Boolean monoid under conjunction (&&).
--
-- -- >>> getAll (All True <> mempty <> All False) -- False ---- --
-- >>> getAll (mconcat (map (\x -> All (even x)) [2,4,6,7,8])) -- False --newtype All All :: Bool -> All [getAll] :: All -> Bool -- | Boolean monoid under disjunction (||). -- --
-- >>> getAny (Any True <> mempty <> Any False) -- True ---- --
-- >>> getAny (mconcat (map (\x -> Any (even x)) [2,4,6,7,8])) -- True --newtype Any Any :: Bool -> Any [getAny] :: Any -> Bool -- | Monoid under addition. -- --
-- >>> getSum (Sum 1 <> Sum 2 <> mempty) -- 3 --newtype Sum a Sum :: a -> Sum a [getSum] :: Sum a -> a -- | Monoid under multiplication. -- --
-- >>> getProduct (Product 3 <> Product 4 <> mempty) -- 12 --newtype Product a Product :: a -> Product a [getProduct] :: Product a -> a -- | Monoid under <|>. newtype Alt (f :: k -> Type) (a :: k) Alt :: f a -> Alt (f :: k -> Type) (a :: k) [getAlt] :: Alt (f :: k -> Type) (a :: k) -> f a -- | Convert an integer into an unknown type-level natural. someNatVal :: Natural -> SomeNat natVal :: forall (n :: Nat) proxy. KnownNat n => proxy n -> Natural -- | This type represents unknown type-level natural numbers. data SomeNat SomeNat :: Proxy n -> SomeNat -- | The unfoldr function is a `dual' to foldr: while -- foldr reduces a list to a summary value, unfoldr builds -- a list from a seed value. The function takes the element and returns -- Nothing if it is done producing the list or returns Just -- (a,b), in which case, a is a prepended to the list -- and b is used as the next element in a recursive call. For -- example, -- --
-- iterate f == unfoldr (\x -> Just (x, f x)) ---- -- In some cases, unfoldr can undo a foldr operation: -- --
-- unfoldr f' (foldr f z xs) == xs ---- -- if the following holds: -- --
-- f' (f x y) = Just (x,y) -- f' z = Nothing ---- -- A simple use of unfoldr: -- --
-- >>> unfoldr (\b -> if b == 0 then Nothing else Just (b, b-1)) 10 -- [10,9,8,7,6,5,4,3,2,1] --unfoldr :: (b -> Maybe (a, b)) -> b -> [a] -- | Sort a list by comparing the results of a key function applied to each -- element. sortOn f is equivalent to sortBy (comparing -- f), but has the performance advantage of only evaluating -- f once for each element in the input list. This is called the -- decorate-sort-undecorate paradigm, or Schwartzian transform. -- -- Elements are arranged from from lowest to highest, keeping duplicates -- in the order they appeared in the input. -- --
-- >>> sortOn fst [(2, "world"), (4, "!"), (1, "Hello")] -- [(1,"Hello"),(2,"world"),(4,"!")] --sortOn :: Ord b => (a -> b) -> [a] -> [a] -- | The sortBy function is the non-overloaded version of -- sort. -- --
-- >>> sortBy (\(a,_) (b,_) -> compare a b) [(2, "world"), (4, "!"), (1, "Hello")] -- [(1,"Hello"),(2,"world"),(4,"!")] --sortBy :: (a -> a -> Ordering) -> [a] -> [a] -- | The sort function implements a stable sorting algorithm. It is -- a special case of sortBy, which allows the programmer to supply -- their own comparison function. -- -- Elements are arranged from from lowest to highest, keeping duplicates -- in the order they appeared in the input. -- --
-- >>> sort [1,6,4,3,2,5] -- [1,2,3,4,5,6] --sort :: Ord a => [a] -> [a] -- | The permutations function returns the list of all permutations -- of the argument. -- --
-- >>> permutations "abc" -- ["abc","bac","cba","bca","cab","acb"] --permutations :: [a] -> [[a]] -- | The subsequences function returns the list of all subsequences -- of the argument. -- --
-- >>> subsequences "abc" -- ["","a","b","ab","c","ac","bc","abc"] --subsequences :: [a] -> [[a]] -- | O(n). The tails function returns all final segments of -- the argument, longest first. For example, -- --
-- >>> tails "abc" -- ["abc","bc","c",""] ---- -- Note that tails has the following strictness property: -- tails _|_ = _|_ : _|_ tails :: [a] -> [[a]] -- | The inits function returns all initial segments of the -- argument, shortest first. For example, -- --
-- >>> inits "abc" -- ["","a","ab","abc"] ---- -- Note that inits has the following strictness property: -- inits (xs ++ _|_) = inits xs ++ _|_ -- -- In particular, inits _|_ = [] : _|_ inits :: [a] -> [[a]] -- | The group function takes a list and returns a list of lists -- such that the concatenation of the result is equal to the argument. -- Moreover, each sublist in the result contains only equal elements. For -- example, -- --
-- >>> group "Mississippi" -- ["M","i","ss","i","ss","i","pp","i"] ---- -- It is a special case of groupBy, which allows the programmer to -- supply their own equality test. group :: Eq a => [a] -> [[a]] -- | The genericReplicate function is an overloaded version of -- replicate, which accepts any Integral value as the -- number of repetitions to make. genericReplicate :: Integral i => i -> a -> [a] -- | The genericSplitAt function is an overloaded version of -- splitAt, which accepts any Integral value as the -- position at which to split. genericSplitAt :: Integral i => i -> [a] -> ([a], [a]) -- | The genericDrop function is an overloaded version of -- drop, which accepts any Integral value as the number of -- elements to drop. genericDrop :: Integral i => i -> [a] -> [a] -- | The genericTake function is an overloaded version of -- take, which accepts any Integral value as the number of -- elements to take. genericTake :: Integral i => i -> [a] -> [a] -- | O(n). The genericLength function is an overloaded -- version of length. In particular, instead of returning an -- Int, it returns any type which is an instance of Num. It -- is, however, less efficient than length. -- --
-- >>> genericLength [1, 2, 3] :: Int -- 3 -- -- >>> genericLength [1, 2, 3] :: Float -- 3.0 --genericLength :: Num i => [a] -> i -- | The transpose function transposes the rows and columns of its -- argument. For example, -- --
-- >>> transpose [[1,2,3],[4,5,6]] -- [[1,4],[2,5],[3,6]] ---- -- If some of the rows are shorter than the following rows, their -- elements are skipped: -- --
-- >>> transpose [[10,11],[20],[],[30,31,32]] -- [[10,20,30],[11,31],[32]] --transpose :: [[a]] -> [[a]] -- | intercalate xs xss is equivalent to (concat -- (intersperse xs xss)). It inserts the list xs in -- between the lists in xss and concatenates the result. -- --
-- >>> intercalate ", " ["Lorem", "ipsum", "dolor"] -- "Lorem, ipsum, dolor" --intercalate :: [a] -> [[a]] -> [a] -- | O(n). The intersperse function takes an element and a -- list and `intersperses' that element between the elements of the list. -- For example, -- --
-- >>> intersperse ',' "abcde" -- "a,b,c,d,e" --intersperse :: a -> [a] -> [a] -- | O(min(m,n)). The isPrefixOf function takes two lists and -- returns True iff the first list is a prefix of the second. -- --
-- >>> "Hello" `isPrefixOf` "Hello World!" -- True ---- --
-- >>> "Hello" `isPrefixOf` "Wello Horld!" -- False --isPrefixOf :: Eq a => [a] -> [a] -> Bool -- | Parse a string using the Read instance. Succeeds if there is -- exactly one valid result. -- --
-- >>> readMaybe "123" :: Maybe Int -- Just 123 ---- --
-- >>> readMaybe "hello" :: Maybe Int -- Nothing --readMaybe :: Read a => String -> Maybe a -- | equivalent to readsPrec with a precedence of 0. reads :: Read a => ReadS a -- | Return True if the given value is a Right-value, -- False otherwise. -- --
-- >>> isRight (Left "foo") -- False -- -- >>> isRight (Right 3) -- True ---- -- Assuming a Left value signifies some sort of error, we can use -- isRight to write a very simple reporting function that only -- outputs "SUCCESS" when a computation has succeeded. -- -- This example shows how isRight might be used to avoid pattern -- matching when one does not care about the value contained in the -- constructor: -- --
-- >>> import Control.Monad ( when ) -- -- >>> let report e = when (isRight e) $ putStrLn "SUCCESS" -- -- >>> report (Left "parse error") -- -- >>> report (Right 1) -- SUCCESS --isRight :: Either a b -> Bool -- | Return True if the given value is a Left-value, -- False otherwise. -- --
-- >>> isLeft (Left "foo") -- True -- -- >>> isLeft (Right 3) -- False ---- -- Assuming a Left value signifies some sort of error, we can use -- isLeft to write a very simple error-reporting function that -- does absolutely nothing in the case of success, and outputs "ERROR" if -- any error occurred. -- -- This example shows how isLeft might be used to avoid pattern -- matching when one does not care about the value contained in the -- constructor: -- --
-- >>> import Control.Monad ( when ) -- -- >>> let report e = when (isLeft e) $ putStrLn "ERROR" -- -- >>> report (Right 1) -- -- >>> report (Left "parse error") -- ERROR --isLeft :: Either a b -> Bool -- | Partitions a list of Either into two lists. All the Left -- elements are extracted, in order, to the first component of the -- output. Similarly the Right elements are extracted to the -- second component of the output. -- --
-- >>> let list = [ Left "foo", Right 3, Left "bar", Right 7, Left "baz" ] -- -- >>> partitionEithers list -- (["foo","bar","baz"],[3,7]) ---- -- The pair returned by partitionEithers x should be the -- same pair as (lefts x, rights x): -- --
-- >>> let list = [ Left "foo", Right 3, Left "bar", Right 7, Left "baz" ] -- -- >>> partitionEithers list == (lefts list, rights list) -- True --partitionEithers :: [Either a b] -> ([a], [b]) -- | Extracts from a list of Either all the Right elements. -- All the Right elements are extracted in order. -- --
-- >>> let list = [ Left "foo", Right 3, Left "bar", Right 7, Left "baz" ] -- -- >>> rights list -- [3,7] --rights :: [Either a b] -> [b] -- | Extracts from a list of Either all the Left elements. -- All the Left elements are extracted in order. -- --
-- >>> let list = [ Left "foo", Right 3, Left "bar", Right 7, Left "baz" ] -- -- >>> lefts list -- ["foo","bar","baz"] --lefts :: [Either a b] -> [a] -- |
-- comparing p x y = compare (p x) (p y) ---- -- Useful combinator for use in conjunction with the xxxBy -- family of functions from Data.List, for example: -- --
-- ... sortBy (comparing fst) ... --comparing :: Ord a => (b -> a) -> b -> b -> Ordering -- | The Down type allows you to reverse sort order conveniently. A -- value of type Down a contains a value of type -- a (represented as Down a). If a has -- an Ord instance associated with it then comparing two -- values thus wrapped will give you the opposite of their normal sort -- order. This is particularly useful when sorting in generalised list -- comprehensions, as in: then sortWith by Down x newtype Down a Down :: a -> Down a -- | Proxy is a type that holds no data, but has a phantom parameter -- of arbitrary type (or even kind). Its use is to provide type -- information, even though there is no value available of that type (or -- it may be too costly to create one). -- -- Historically, Proxy :: Proxy a is a safer -- alternative to the undefined :: a idiom. -- --
-- >>> Proxy :: Proxy (Void, Int -> Int) -- Proxy ---- -- Proxy can even hold types of higher kinds, -- --
-- >>> Proxy :: Proxy Either -- Proxy ---- --
-- >>> Proxy :: Proxy Functor -- Proxy ---- --
-- >>> Proxy :: Proxy complicatedStructure -- Proxy --data Proxy (t :: k) Proxy :: Proxy (t :: k) -- | See openFile data IOMode ReadMode :: IOMode WriteMode :: IOMode AppendMode :: IOMode ReadWriteMode :: IOMode -- | Reverse order of bytes in Word64. byteSwap64 :: Word64 -> Word64 -- | Reverse order of bytes in Word32. byteSwap32 :: Word32 -> Word32 -- | Swap bytes in Word16. byteSwap16 :: Word16 -> Word16 integralEnumFromThenTo :: Integral a => a -> a -> a -> [a] integralEnumFromTo :: Integral a => a -> a -> [a] integralEnumFromThen :: (Integral a, Bounded a) => a -> a -> [a] integralEnumFrom :: (Integral a, Bounded a) => a -> [a] gcdWord' :: Word -> Word -> Word gcdInt' :: Int -> Int -> Int -- | lcm x y is the smallest positive integer that both -- x and y divide. lcm :: Integral a => a -> a -> a -- | gcd x y is the non-negative factor of both x -- and y of which every common factor of x and -- y is also a factor; for example gcd 4 2 = 2, -- gcd (-4) 6 = 2, gcd 0 4 = 4. -- gcd 0 0 = 0. (That is, the common divisor -- that is "greatest" in the divisibility preordering.) -- -- Note: Since for signed fixed-width integer types, abs -- minBound < 0, the result may be negative if one of the -- arguments is minBound (and necessarily is if the other -- is 0 or minBound) for such types. gcd :: Integral a => a -> a -> a (^^%^^) :: Integral a => Rational -> a -> Rational (^%^) :: Integral a => Rational -> a -> Rational -- | raise a number to an integral power (^^) :: (Fractional a, Integral b) => a -> b -> a infixr 8 ^^ odd :: Integral a => a -> Bool even :: Integral a => a -> Bool numericEnumFromThenTo :: (Ord a, Fractional a) => a -> a -> a -> [a] numericEnumFromTo :: (Ord a, Fractional a) => a -> a -> [a] numericEnumFromThen :: Fractional a => a -> a -> [a] numericEnumFrom :: Fractional a => a -> [a] -- | Extract the denominator of the ratio in reduced form: the numerator -- and denominator have no common factor and the denominator is positive. denominator :: Ratio a -> a -- | Extract the numerator of the ratio in reduced form: the numerator and -- denominator have no common factor and the denominator is positive. numerator :: Ratio a -> a -- | reduce is a subsidiary function used only in this module. It -- normalises a ratio by dividing both numerator and denominator by their -- greatest common divisor. reduce :: Integral a => a -> a -> Ratio a notANumber :: Rational infinity :: Rational ratioPrec1 :: Int ratioPrec :: Int underflowError :: a overflowError :: a ratioZeroDenominatorError :: a divZeroError :: a boundedEnumFromThen :: (Enum a, Bounded a) => a -> a -> [a] boundedEnumFrom :: (Enum a, Bounded a) => a -> [a] -- | The toEnum method restricted to the type Char. chr :: Int -> Char -- | The unzip3 function takes a list of triples and returns three -- lists, analogous to unzip. unzip3 :: [(a, b, c)] -> ([a], [b], [c]) -- | unzip transforms a list of pairs into a list of first -- components and a list of second components. unzip :: [(a, b)] -> ([a], [b]) -- | O(min(m,n)). zipWith generalises zip by zipping -- with the function given as the first argument, instead of a tupling -- function. For example, zipWith (+) is applied to two -- lists to produce the list of corresponding sums: -- --
-- >>> zipWith (+) [1, 2, 3] [4, 5, 6] -- [5,7,9] ---- -- zipWith is right-lazy: -- --
-- zipWith f [] _|_ = [] ---- -- zipWith is capable of list fusion, but it is restricted to its -- first list argument and its resulting list. zipWith :: (a -> b -> c) -> [a] -> [b] -> [c] -- | zip3 takes three lists and returns a list of triples, analogous -- to zip. It is capable of list fusion, but it is restricted to -- its first list argument and its resulting list. zip3 :: [a] -> [b] -> [c] -> [(a, b, c)] -- | reverse xs returns the elements of xs in -- reverse order. xs must be finite. reverse :: [a] -> [a] -- | break, applied to a predicate p and a list -- xs, returns a tuple where first element is longest prefix -- (possibly empty) of xs of elements that do not satisfy -- p and second element is the remainder of the list: -- --
-- break (> 3) [1,2,3,4,1,2,3,4] == ([1,2,3],[4,1,2,3,4]) -- break (< 9) [1,2,3] == ([],[1,2,3]) -- break (> 9) [1,2,3] == ([1,2,3],[]) ---- -- break p is equivalent to span (not . -- p). break :: (a -> Bool) -> [a] -> ([a], [a]) -- | splitAt n xs returns a tuple where first element is -- xs prefix of length n and second element is the -- remainder of the list: -- --
-- splitAt 6 "Hello World!" == ("Hello ","World!")
-- splitAt 3 [1,2,3,4,5] == ([1,2,3],[4,5])
-- splitAt 1 [1,2,3] == ([1],[2,3])
-- splitAt 3 [1,2,3] == ([1,2,3],[])
-- splitAt 4 [1,2,3] == ([1,2,3],[])
-- splitAt 0 [1,2,3] == ([],[1,2,3])
-- splitAt (-1) [1,2,3] == ([],[1,2,3])
--
--
-- It is equivalent to (take n xs, drop n xs) when
-- n is not _|_ (splitAt _|_ xs = _|_).
-- splitAt is an instance of the more general
-- genericSplitAt, in which n may be of any integral
-- type.
splitAt :: Int -> [a] -> ([a], [a])
-- | drop n xs returns the suffix of xs after the
-- first n elements, or [] if n > length
-- xs:
--
-- -- drop 6 "Hello World!" == "World!" -- drop 3 [1,2,3,4,5] == [4,5] -- drop 3 [1,2] == [] -- drop 3 [] == [] -- drop (-1) [1,2] == [1,2] -- drop 0 [1,2] == [1,2] ---- -- It is an instance of the more general genericDrop, in which -- n may be of any integral type. drop :: Int -> [a] -> [a] -- | take n, applied to a list xs, returns the -- prefix of xs of length n, or xs itself if -- n > length xs: -- --
-- take 5 "Hello World!" == "Hello" -- take 3 [1,2,3,4,5] == [1,2,3] -- take 3 [1,2] == [1,2] -- take 3 [] == [] -- take (-1) [1,2] == [] -- take 0 [1,2] == [] ---- -- It is an instance of the more general genericTake, in which -- n may be of any integral type. take :: Int -> [a] -> [a] -- | dropWhile p xs returns the suffix remaining after -- takeWhile p xs: -- --
-- dropWhile (< 3) [1,2,3,4,5,1,2,3] == [3,4,5,1,2,3] -- dropWhile (< 9) [1,2,3] == [] -- dropWhile (< 0) [1,2,3] == [1,2,3] --dropWhile :: (a -> Bool) -> [a] -> [a] -- | takeWhile, applied to a predicate p and a list -- xs, returns the longest prefix (possibly empty) of -- xs of elements that satisfy p: -- --
-- takeWhile (< 3) [1,2,3,4,1,2,3,4] == [1,2] -- takeWhile (< 9) [1,2,3] == [1,2,3] -- takeWhile (< 0) [1,2,3] == [] --takeWhile :: (a -> Bool) -> [a] -> [a] -- | cycle ties a finite list into a circular one, or equivalently, -- the infinite repetition of the original list. It is the identity on -- infinite lists. cycle :: [a] -> [a] -- | replicate n x is a list of length n with -- x the value of every element. It is an instance of the more -- general genericReplicate, in which n may be of any -- integral type. replicate :: Int -> a -> [a] -- | repeat x is an infinite list, with x the -- value of every element. repeat :: a -> [a] -- | iterate f x returns an infinite list of repeated -- applications of f to x: -- --
-- iterate f x == [x, f x, f (f x), ...] ---- -- Note that iterate is lazy, potentially leading to thunk -- build-up if the consumer doesn't force each iterate. See -- iterate' for a strict variant of this function. iterate :: (a -> a) -> a -> [a] -- | O(n). scanr is the right-to-left dual of scanl. -- Note that -- --
-- head (scanr f z xs) == foldr f z xs. --scanr :: (a -> b -> b) -> b -> [a] -> [b] -- | O(n). scanl is similar to foldl, but returns a -- list of successive reduced values from the left: -- --
-- scanl f z [x1, x2, ...] == [z, z `f` x1, (z `f` x1) `f` x2, ...] ---- -- Note that -- --
-- last (scanl f z xs) == foldl f z xs. --scanl :: (b -> a -> b) -> b -> [a] -> [b] -- | The mapMaybe function is a version of map which can -- throw out elements. In particular, the functional argument returns -- something of type Maybe b. If this is Nothing, -- no element is added on to the result list. If it is Just -- b, then b is included in the result list. -- --
-- >>> import Text.Read ( readMaybe ) -- -- >>> let readMaybeInt = readMaybe :: String -> Maybe Int -- -- >>> mapMaybe readMaybeInt ["1", "Foo", "3"] -- [1,3] -- -- >>> catMaybes $ map readMaybeInt ["1", "Foo", "3"] -- [1,3] ---- -- If we map the Just constructor, the entire list should be -- returned: -- --
-- >>> mapMaybe Just [1,2,3] -- [1,2,3] --mapMaybe :: (a -> Maybe b) -> [a] -> [b] -- | The catMaybes function takes a list of Maybes and -- returns a list of all the Just values. -- --
-- >>> catMaybes [Just 1, Nothing, Just 3] -- [1,3] ---- -- When constructing a list of Maybe values, catMaybes can -- be used to return all of the "success" results (if the list is the -- result of a map, then mapMaybe would be more -- appropriate): -- --
-- >>> import Text.Read ( readMaybe ) -- -- >>> [readMaybe x :: Maybe Int | x <- ["1", "Foo", "3"] ] -- [Just 1,Nothing,Just 3] -- -- >>> catMaybes $ [readMaybe x :: Maybe Int | x <- ["1", "Foo", "3"] ] -- [1,3] --catMaybes :: [Maybe a] -> [a] -- | The listToMaybe function returns Nothing on an empty -- list or Just a where a is the first element -- of the list. -- --
-- >>> listToMaybe [] -- Nothing ---- --
-- >>> listToMaybe [9] -- Just 9 ---- --
-- >>> listToMaybe [1,2,3] -- Just 1 ---- -- Composing maybeToList with listToMaybe should be the -- identity on singleton/empty lists: -- --
-- >>> maybeToList $ listToMaybe [5] -- [5] -- -- >>> maybeToList $ listToMaybe [] -- [] ---- -- But not on lists with more than one element: -- --
-- >>> maybeToList $ listToMaybe [1,2,3] -- [1] --listToMaybe :: [a] -> Maybe a -- | The maybeToList function returns an empty list when given -- Nothing or a singleton list when given Just. -- --
-- >>> maybeToList (Just 7) -- [7] ---- --
-- >>> maybeToList Nothing -- [] ---- -- One can use maybeToList to avoid pattern matching when combined -- with a function that (safely) works on lists: -- --
-- >>> import Text.Read ( readMaybe ) -- -- >>> sum $ maybeToList (readMaybe "3") -- 3 -- -- >>> sum $ maybeToList (readMaybe "") -- 0 --maybeToList :: Maybe a -> [a] -- | The fromMaybe function takes a default value and and -- Maybe value. If the Maybe is Nothing, it returns -- the default values; otherwise, it returns the value contained in the -- Maybe. -- --
-- >>> fromMaybe "" (Just "Hello, World!") -- "Hello, World!" ---- --
-- >>> fromMaybe "" Nothing -- "" ---- -- Read an integer from a string using readMaybe. If we fail to -- parse an integer, we want to return 0 by default: -- --
-- >>> import Text.Read ( readMaybe ) -- -- >>> fromMaybe 0 (readMaybe "5") -- 5 -- -- >>> fromMaybe 0 (readMaybe "") -- 0 --fromMaybe :: a -> Maybe a -> a -- | The isNothing function returns True iff its argument is -- Nothing. -- --
-- >>> isNothing (Just 3) -- False ---- --
-- >>> isNothing (Just ()) -- False ---- --
-- >>> isNothing Nothing -- True ---- -- Only the outer constructor is taken into consideration: -- --
-- >>> isNothing (Just Nothing) -- False --isNothing :: Maybe a -> Bool -- | The isJust function returns True iff its argument is of -- the form Just _. -- --
-- >>> isJust (Just 3) -- True ---- --
-- >>> isJust (Just ()) -- True ---- --
-- >>> isJust Nothing -- False ---- -- Only the outer constructor is taken into consideration: -- --
-- >>> isJust (Just Nothing) -- True --isJust :: Maybe a -> Bool -- | The maybe function takes a default value, a function, and a -- Maybe value. If the Maybe value is Nothing, the -- function returns the default value. Otherwise, it applies the function -- to the value inside the Just and returns the result. -- --
-- >>> maybe False odd (Just 3) -- True ---- --
-- >>> maybe False odd Nothing -- False ---- -- Read an integer from a string using readMaybe. If we succeed, -- return twice the integer; that is, apply (*2) to it. If -- instead we fail to parse an integer, return 0 by default: -- --
-- >>> import Text.Read ( readMaybe ) -- -- >>> maybe 0 (*2) (readMaybe "5") -- 10 -- -- >>> maybe 0 (*2) (readMaybe "") -- 0 ---- -- Apply show to a Maybe Int. If we have Just n, -- we want to show the underlying Int n. But if we have -- Nothing, we return the empty string instead of (for example) -- "Nothing": -- --
-- >>> maybe "" show (Just 5) -- "5" -- -- >>> maybe "" show Nothing -- "" --maybe :: b -> (a -> b) -> Maybe a -> b -- | Case analysis for the Bool type. bool x y p -- evaluates to x when p is False, and evaluates -- to y when p is True. -- -- This is equivalent to if p then y else x; that is, one can -- think of it as an if-then-else construct with its arguments reordered. -- --
-- >>> bool "foo" "bar" True -- "bar" -- -- >>> bool "foo" "bar" False -- "foo" ---- -- Confirm that bool x y p and if p then y else -- x are equivalent: -- --
-- >>> let p = True; x = "bar"; y = "foo" -- -- >>> bool x y p == if p then y else x -- True -- -- >>> let p = False -- -- >>> bool x y p == if p then y else x -- True --bool :: a -> a -> Bool -> a -- | & is a reverse application operator. This provides -- notational convenience. Its precedence is one higher than that of the -- forward application operator $, which allows & to be -- nested in $. -- --
-- >>> 5 & (+1) & show -- "6" --(&) :: a -> (a -> b) -> b infixl 1 & -- | on b u x y runs the binary function b -- on the results of applying unary function u to two -- arguments x and y. From the opposite perspective, it -- transforms two inputs and combines the outputs. -- --
-- ((+) `on` f) x y = f x + f y ---- -- Typical usage: sortBy (compare `on` -- fst). -- -- Algebraic properties: -- --
(*) `on` id = (*) -- (if (*) ∉ {⊥, const -- ⊥})
((*) `on` f) `on` g = (*) `on` (f . g)
flip on f . flip on g = flip on (g . -- f)
-- >>> let fac n = if n <= 1 then 1 else n * fac (n-1) in fac 5 -- 120 ---- -- This uses the fact that Haskell’s let introduces recursive -- bindings. We can rewrite this definition using fix, -- --
-- >>> fix (\rec n -> if n <= 1 then 1 else n * rec (n-1)) 5 -- 120 ---- -- Instead of making a recursive call, we introduce a dummy parameter -- rec; when used within fix, this parameter then refers -- to fix argument, hence the recursion is reintroduced. fix :: (a -> a) -> a -- | void value discards or ignores the result of -- evaluation, such as the return value of an IO action. -- --
-- >>> void Nothing -- Nothing -- -- >>> void (Just 3) -- Just () ---- -- Replace the contents of an Either Int -- Int with unit, resulting in an Either -- Int (): -- --
-- >>> void (Left 8675309) -- Left 8675309 -- -- >>> void (Right 8675309) -- Right () ---- -- Replace every element of a list with unit: -- --
-- >>> void [1,2,3] -- [(),(),()] ---- -- Replace the second element of a pair with unit: -- --
-- >>> void (1,2) -- (1,()) ---- -- Discard the result of an IO action: -- --
-- >>> mapM print [1,2] -- 1 -- 2 -- [(),()] -- -- >>> void $ mapM print [1,2] -- 1 -- 2 --void :: Functor f => f a -> f () -- | Flipped version of <$. -- --
-- >>> Nothing $> "foo" -- Nothing -- -- >>> Just 90210 $> "foo" -- Just "foo" ---- -- Replace the contents of an Either Int -- Int with a constant String, resulting in an -- Either Int String: -- --
-- >>> Left 8675309 $> "foo" -- Left 8675309 -- -- >>> Right 8675309 $> "foo" -- Right "foo" ---- -- Replace each element of a list with a constant String: -- --
-- >>> [1,2,3] $> "foo" -- ["foo","foo","foo"] ---- -- Replace the second element of a pair with a constant String: -- --
-- >>> (1,2) $> "foo" -- (1,"foo") --($>) :: Functor f => f a -> b -> f b infixl 4 $> -- | Flipped version of <$>. -- --
-- (<&>) = flip fmap ---- --
-- >>> Just 2 <&> (+1) -- Just 3 ---- --
-- >>> [1,2,3] <&> (+1) -- [2,3,4] ---- --
-- >>> Right 3 <&> (+1) -- Right 4 --(<&>) :: Functor f => f a -> (a -> b) -> f b infixl 1 <&> -- | Swap the components of a pair. swap :: (a, b) -> (b, a) -- | uncurry converts a curried function to a function on pairs. -- --
-- >>> uncurry (+) (1,2) -- 3 ---- --
-- >>> uncurry ($) (show, 1) -- "1" ---- --
-- >>> map (uncurry max) [(1,2), (3,4), (6,8)] -- [2,4,8] --uncurry :: (a -> b -> c) -> (a, b) -> c -- | curry converts an uncurried function to a curried function. -- --
-- >>> curry fst 1 2 -- 1 --curry :: ((a, b) -> c) -> a -> b -> c -- | An MVar (pronounced "em-var") is a synchronising variable, used -- for communication between concurrent threads. It can be thought of as -- a box, which may be empty or full. data MVar a -- | the same as flip (-). -- -- Because - is treated specially in the Haskell grammar, -- (- e) is not a section, but an application of -- prefix negation. However, (subtract -- exp) is equivalent to the disallowed section. subtract :: Num a => a -> a -> a -- | Returns a [String] representing the current call stack. This -- can be useful for debugging. -- -- The implementation uses the call-stack simulation maintained by the -- profiler, so it only works if the program was compiled with -- -prof and contains suitable SCC annotations (e.g. by using -- -fprof-auto). Otherwise, the list returned is likely to be -- empty or uninformative. currentCallStack :: IO [String] -- | asTypeOf is a type-restricted version of const. It is -- usually used as an infix operator, and its typing forces its first -- argument (which is usually overloaded) to have the same type as the -- second. asTypeOf :: a -> a -> a -- | flip f takes its (first) two arguments in the reverse -- order of f. -- --
-- >>> flip (++) "hello" "world" -- "worldhello" --flip :: (a -> b -> c) -> b -> a -> c maxInt :: Int minInt :: Int -- | The fromEnum method restricted to the type Char. ord :: Char -> Int -- | In many situations, the liftM operations can be replaced by -- uses of ap, which promotes function application. -- --
-- return f `ap` x1 `ap` ... `ap` xn ---- -- is equivalent to -- --
-- liftMn f x1 x2 ... xn --ap :: Monad m => m (a -> b) -> m a -> m b -- | Promote a function to a monad, scanning the monadic arguments from -- left to right (cf. liftM2). liftM5 :: Monad m => (a1 -> a2 -> a3 -> a4 -> a5 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m a5 -> m r -- | Promote a function to a monad, scanning the monadic arguments from -- left to right (cf. liftM2). liftM4 :: Monad m => (a1 -> a2 -> a3 -> a4 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m r -- | Promote a function to a monad, scanning the monadic arguments from -- left to right (cf. liftM2). liftM3 :: Monad m => (a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r -- | Promote a function to a monad, scanning the monadic arguments from -- left to right. For example, -- --
-- liftM2 (+) [0,1] [0,2] = [0,2,1,3] -- liftM2 (+) (Just 1) Nothing = Nothing --liftM2 :: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r -- | Same as >>=, but with the arguments interchanged. (=<<) :: Monad m => (a -> m b) -> m a -> m b infixr 1 =<< -- | Lift a ternary function to actions. liftA3 :: Applicative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d -- | A variant of <*> with the arguments reversed. (<**>) :: Applicative f => f a -> f (a -> b) -> f b infixl 4 <**> -- | Non-empty (and non-strict) list type. data NonEmpty a (:|) :: a -> [a] -> NonEmpty a infixr 5 :| -- | Extract a list of call-sites from the CallStack. -- -- The list is ordered by most recent call. getCallStack :: CallStack -> [([Char], SrcLoc)] -- | Request a CallStack. -- -- NOTE: The implicit parameter ?callStack :: CallStack is an -- implementation detail and should not be considered part of the -- CallStack API, we may decide to change the implementation in -- the future. type HasCallStack = ?callStack :: CallStack -- | This is a valid definition of stimes for an idempotent -- Monoid. -- -- When mappend x x = x, this definition should be preferred, -- because it works in O(1) rather than O(log n) stimesIdempotentMonoid :: (Integral b, Monoid a) => b -> a -> a -- | The SomeException type is the root of the exception type -- hierarchy. When an exception of type e is thrown, behind the -- scenes it is encapsulated in a SomeException. data SomeException SomeException :: e -> SomeException -- | The trivial monad transformer, which maps a monad to an equivalent -- monad. data IdentityT (f :: k -> Type) (a :: k) -- | A map of integers to values a. data IntMap a -- | A set of integers. data IntSet -- | General-purpose finite sequences. data Seq a -- | A set of values a. data Set a -- | A class of types that can be fully evaluated. class NFData a -- | rnf should reduce its argument to normal form (that is, fully -- evaluate all sub-components), and then return (). -- --
-- {-# LANGUAGE DeriveGeneric #-}
--
-- import GHC.Generics (Generic, Generic1)
-- import Control.DeepSeq
--
-- data Foo a = Foo a String
-- deriving (Eq, Generic, Generic1)
--
-- instance NFData a => NFData (Foo a)
-- instance NFData1 Foo
--
-- data Colour = Red | Green | Blue
-- deriving Generic
--
-- instance NFData Colour
--
--
-- Starting with GHC 7.10, the example above can be written more
-- concisely by enabling the new DeriveAnyClass extension:
--
--
-- {-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}
--
-- import GHC.Generics (Generic)
-- import Control.DeepSeq
--
-- data Foo a = Foo a String
-- deriving (Eq, Generic, Generic1, NFData, NFData1)
--
-- data Colour = Red | Green | Blue
-- deriving (Generic, NFData)
--
--
-- -- rnf a = seq a () ---- -- However, starting with deepseq-1.4.0.0, the default -- implementation is based on DefaultSignatures allowing for -- more accurate auto-derived NFData instances. If you need the -- previously used exact default rnf method implementation -- semantics, use -- --
-- instance NFData Colour where rnf x = seq x () ---- -- or alternatively -- --
-- instance NFData Colour where rnf = rwhnf ---- -- or -- --
-- {-# LANGUAGE BangPatterns #-}
-- instance NFData Colour where rnf !_ = ()
--
rnf :: NFData a => a -> ()
-- | a variant of deepseq that is useful in some circumstances:
--
-- -- force x = x `deepseq` x ---- -- force x fully evaluates x, and then returns it. Note -- that force x only performs evaluation when the value of -- force x itself is demanded, so essentially it turns shallow -- evaluation into deep evaluation. -- -- force can be conveniently used in combination with -- ViewPatterns: -- --
-- {-# LANGUAGE BangPatterns, ViewPatterns #-}
-- import Control.DeepSeq
--
-- someFun :: ComplexData -> SomeResult
-- someFun (force -> !arg) = {- 'arg' will be fully evaluated -}
--
--
-- Another useful application is to combine force with
-- evaluate in order to force deep evaluation relative to other
-- IO operations:
--
--
-- import Control.Exception (evaluate)
-- import Control.DeepSeq
--
-- main = do
-- result <- evaluate $ force $ pureComputation
-- {- 'result' will be fully evaluated at this point -}
-- return ()
--
--
-- Finally, here's an exception safe variant of the readFile'
-- example:
--
-- -- readFile' :: FilePath -> IO String -- readFile' fn = bracket (openFile fn ReadMode) hClose $ \h -> -- evaluate . force =<< hGetContents h --force :: NFData a => a -> a -- | the deep analogue of $!. In the expression f $!! x, -- x is fully evaluated before the function f is -- applied to it. ($!!) :: NFData a => (a -> b) -> a -> b infixr 0 $!! -- | deepseq: fully evaluates the first argument, before returning -- the second. -- -- The name deepseq is used to illustrate the relationship to -- seq: where seq is shallow in the sense that it only -- evaluates the top level of its argument, deepseq traverses the -- entire data structure evaluating it completely. -- -- deepseq can be useful for forcing pending exceptions, -- eradicating space leaks, or forcing lazy I/O to happen. It is also -- useful in conjunction with parallel Strategies (see the -- parallel package). -- -- There is no guarantee about the ordering of evaluation. The -- implementation may evaluate the components of the structure in any -- order or in parallel. To impose an actual order on evaluation, use -- pseq from Control.Parallel in the parallel -- package. deepseq :: NFData a => a -> b -> b -- | The parameterizable maybe monad, obtained by composing an arbitrary -- monad with the Maybe monad. -- -- Computations are actions that may produce a value or exit. -- -- The return function yields a computation that produces that -- value, while >>= sequences two subcomputations, exiting -- if either computation does. newtype MaybeT (m :: Type -> Type) a MaybeT :: m (Maybe a) -> MaybeT (m :: Type -> Type) a [runMaybeT] :: MaybeT (m :: Type -> Type) a -> m (Maybe a) -- | A monad transformer that adds exceptions to other monads. -- -- ExceptT constructs a monad parameterized over two things: -- --
-- throwM e >> x = throwM e ---- -- In other words, throwing an exception short-circuits the rest of the -- monadic computation. class Monad m => MonadThrow (m :: Type -> Type) -- | A class for monads which allow exceptions to be caught, in particular -- exceptions which were thrown by throwM. -- -- Instances should obey the following law: -- --
-- catch (throwM e) f = f e ---- -- Note that the ability to catch an exception does not guarantee -- that we can deal with all possible exit points from a computation. -- Some monads, such as continuation-based stacks, allow for more than -- just a success/failure strategy, and therefore catch -- cannot be used by those monads to properly implement a function -- such as finally. For more information, see MonadMask. class MonadThrow m => MonadCatch (m :: Type -> Type) -- | A class for monads which provide for the ability to account for all -- possible exit points from a computation, and to mask asynchronous -- exceptions. Continuation-based monads are invalid instances of this -- class. -- -- Instances should ensure that, in the following code: -- --
-- fg = f `finally` g ---- -- The action g is called regardless of what occurs within -- f, including async exceptions. Some monads allow f -- to abort the computation via other effects than throwing an exception. -- For simplicity, we will consider aborting and throwing an exception to -- be two forms of "throwing an error". -- -- If f and g both throw an error, the error thrown by -- fg depends on which errors we're talking about. In a monad -- transformer stack, the deeper layers override the effects of the inner -- layers; for example, ExceptT e1 (Except e2) a represents a -- value of type Either e2 (Either e1 a), so throwing both an -- e1 and an e2 will result in Left e2. If -- f and g both throw an error from the same layer, -- instances should ensure that the error from g wins. -- -- Effects other than throwing an error are also overriden by the deeper -- layers. For example, StateT s Maybe a represents a value of -- type s -> Maybe (a, s), so if an error thrown from -- f causes this function to return Nothing, any -- changes to the state which f also performed will be erased. -- As a result, g will see the state as it was before -- f. Once g completes, f's error will be -- rethrown, so g' state changes will be erased as well. This is -- the normal interaction between effects in a monad transformer stack. -- -- By contrast, lifted-base's version of finally always -- discards all of g's non-IO effects, and g never sees -- any of f's non-IO effects, regardless of the layer ordering -- and regardless of whether f throws an error. This is not the -- result of interacting effects, but a consequence of -- MonadBaseControl's approach. class MonadCatch m => MonadMask (m :: Type -> Type) -- | Runs an action with asynchronous exceptions disabled. The action is -- provided a method for restoring the async. environment to what it was -- at the mask call. See Control.Exception's mask. mask :: MonadMask m => ((forall a. () => m a -> m a) -> m b) -> m b -- | Like mask, but the masked computation is not interruptible (see -- Control.Exception's uninterruptibleMask. WARNING: Only -- use if you need to mask exceptions around an interruptible operation -- AND you can guarantee the interruptible operation will only block for -- a short period of time. Otherwise you render the program/thread -- unresponsive and/or unkillable. uninterruptibleMask :: MonadMask m => ((forall a. () => m a -> m a) -> m b) -> m b -- | A generalized version of bracket which uses ExitCase to -- distinguish the different exit cases, and returns the values of both -- the use and release actions. In practice, this extra -- information is rarely needed, so it is often more convenient to use -- one of the simpler functions which are defined in terms of this one, -- such as bracket, finally, onError, and -- bracketOnError. -- -- This function exists because in order to thread their effects through -- the execution of bracket, monad transformers need values to be -- threaded from use to release and from -- release to the output value. -- -- NOTE This method was added in version 0.9.0 of this library. -- Previously, implementation of functions like bracket and -- finally in this module were based on the mask and -- uninterruptibleMask functions only, disallowing some classes of -- tranformers from having MonadMask instances (notably -- multi-exit-point transformers like ExceptT). If you are a -- library author, you'll now need to provide an implementation for this -- method. The StateT implementation demonstrates most of the -- subtleties: -- --
-- generalBracket acquire release use = StateT $ s0 -> do -- ((b, _s2), (c, s3)) <- generalBracket -- (runStateT acquire s0) -- ((resource, s1) exitCase -> case exitCase of -- ExitCaseSuccess (b, s2) -> runStateT (release resource (ExitCaseSuccess b)) s2 -- -- -- In the two other cases, the base monad overrides use's state -- -- changes and the state reverts to s1. -- ExitCaseException e -> runStateT (release resource (ExitCaseException e)) s1 -- ExitCaseAbort -> runStateT (release resource ExitCaseAbort) s1 -- ) -- ((resource, s1) -> runStateT (use resource) s1) -- return ((b, c), s3) ---- -- The StateT s m implementation of generalBracket -- delegates to the m implementation of generalBracket. -- The acquire, use, and release arguments -- given to StateT's implementation produce actions of type -- StateT s m a, StateT s m b, and StateT s m -- c. In order to run those actions in the base monad, we need to -- call runStateT, from which we obtain actions of type m -- (a, s), m (b, s), and m (c, s). Since each -- action produces the next state, it is important to feed the state -- produced by the previous action to the next action. -- -- In the ExitCaseSuccess case, the state starts at s0, -- flows through acquire to become s1, flows through -- use to become s2, and finally flows through -- release to become s3. In the other two cases, -- release does not receive the value s2, so its action -- cannot see the state changes performed by use. This is fine, -- because in those two cases, an error was thrown in the base monad, so -- as per the usual interaction between effects in a monad transformer -- stack, those state changes get reverted. So we start from s1 -- instead. -- -- Finally, the m implementation of generalBracket -- returns the pairs (b, s) and (c, s). For monad -- transformers other than StateT, this will be some other type -- representing the effects and values performed and returned by the -- use and release actions. The effect part of the -- use result, in this case _s2, usually needs to be -- discarded, since those effects have already been incorporated in the -- release action. -- -- The only effect which is intentionally not incorporated in the -- release action is the effect of throwing an error. In that -- case, the error must be re-thrown. One subtlety which is easy to miss -- is that in the case in which use and release both -- throw an error, the error from release should take priority. -- Here is an implementation for ExceptT which demonstrates how -- to do this. -- --
-- generalBracket acquire release use = ExceptT $ do -- (eb, ec) <- generalBracket -- (runExceptT acquire) -- (eresource exitCase -> case eresource of -- Left e -> return (Left e) -- nothing to release, acquire didn't succeed -- Right resource -> case exitCase of -- ExitCaseSuccess (Right b) -> runExceptT (release resource (ExitCaseSuccess b)) -- ExitCaseException e -> runExceptT (release resource (ExitCaseException e)) -- _ -> runExceptT (release resource ExitCaseAbort)) -- (either (return . Left) (runExceptT . use)) -- return $ do -- -- The order in which we perform those two Either effects determines -- -- which error will win if they are both Lefts. We want the error from -- -- release to win. -- c <- ec -- b <- eb -- return (b, c) --generalBracket :: MonadMask m => m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c) -- | O(n) Convert a lazy Text into a strict Text. toStrict :: Text -> Text -- | A set of values. A set cannot contain duplicate values. data HashSet a -- | A state transformer monad parameterized by: -- --
-- f :: Either String $ Maybe Int -- = -- f :: Either String (Maybe Int) --type (f :: k1 -> k) $ (a :: k1) = f a infixr 2 $ -- | undefined that leaves a warning in code on every usage. undefined :: forall (r :: RuntimeRep) (a :: TYPE r). HasCallStack => a -- | error that takes Text as an argument. error :: forall (r :: RuntimeRep) (a :: TYPE r). HasCallStack => Text -> a -- | s ^.. t returns the list of all values that t gets -- from s. -- -- A Maybe contains either 0 or 1 values: -- --
-- >>> Just 3 ^.. _Just -- [3] ---- -- Gathering all values in a list of tuples: -- --
-- >>> [(1,2),(3,4)] ^.. each.each -- [1,2,3,4] --(^..) :: s -> Getting (Endo [a]) s a -> [a] infixl 8 ^.. -- | set is a synonym for (.~). -- -- Setting the 1st component of a pair: -- --
-- set _1 :: x -> (a, b) -> (x, b) -- set _1 = \x t -> (x, snd t) ---- -- Using it to rewrite (<$): -- --
-- set mapped :: Functor f => a -> f b -> f a -- set mapped = (<$) --set :: ASetter s t a b -> b -> s -> t -- | (.~) assigns a value to the target. It's the same thing as -- using (%~) with const: -- --
-- l .~ x = l %~ const x ---- -- See set if you want a non-operator synonym. -- -- Here it is used to change 2 fields of a 3-tuple: -- --
-- >>> (0,0,0) & _1 .~ 1 & _3 .~ 3 -- (1,0,3) --(.~) :: ASetter s t a b -> b -> s -> t infixr 4 .~ -- | over is a synonym for (%~). -- -- Getting fmap in a roundabout way: -- --
-- over mapped :: Functor f => (a -> b) -> f a -> f b -- over mapped = fmap ---- -- Applying a function to both components of a pair: -- --
-- over both :: (a -> b) -> (a, a) -> (b, b) -- over both = \f t -> (f (fst t), f (snd t)) ---- -- Using over _2 as a replacement for -- second: -- --
-- >>> over _2 show (10,20) -- (10,"20") --over :: ASetter s t a b -> (a -> b) -> s -> t -- | Gives access to the 1st field of a tuple (up to 5-tuples). -- -- Getting the 1st component: -- --
-- >>> (1,2,3,4,5) ^. _1 -- 1 ---- -- Setting the 1st component: -- --
-- >>> (1,2,3) & _1 .~ 10 -- (10,2,3) ---- -- Note that this lens is lazy, and can set fields even of -- undefined: -- --
-- >>> set _1 10 undefined :: (Int, Int) -- (10,*** Exception: Prelude.undefined ---- -- This is done to avoid violating a lens law stating that you can get -- back what you put: -- --
-- >>> view _1 . set _1 10 $ (undefined :: (Int, Int)) -- 10 ---- -- The implementation (for 2-tuples) is: -- --
-- _1 f t = (,) <$> f (fst t) -- <*> pure (snd t) ---- -- or, alternatively, -- --
-- _1 f ~(a,b) = (\a' -> (a',b)) <$> f a ---- -- (where ~ means a lazy pattern). -- -- _2, _3, _4, and _5 are also available (see -- below). _1 :: Field1 s t a b => Lens s t a b _2 :: Field2 s t a b => Lens s t a b _3 :: Field3 s t a b => Lens s t a b _4 :: Field4 s t a b => Lens s t a b _5 :: Field5 s t a b => Lens s t a b -- | Lens s t a b is the lowest common denominator of a setter and -- a getter, something that has the power of both; it has a -- Functor constraint, and since both Const and -- Identity are functors, it can be used whenever a getter or a -- setter is needed. -- --
-- t pure ≡ pure -- fmap (t f) . t g ≡ getCompose . t (Compose . fmap f . g) ---- -- The 1st law states that you can't change the shape of the structure or -- do anything funny with elements (traverse elements which aren't in the -- structure, create new elements out of thin air, etc.). The 2nd law -- states that you should be able to fuse 2 identical traversals into -- one. For a more detailed explanation of the laws, see this blog -- post (if you prefer rambling blog posts), or The Essence Of The -- Iterator Pattern (if you prefer papers). -- -- Traversing any value twice is a violation of traversal laws. You can, -- however, traverse values in any order. type Traversal s t a b = forall (f :: Type -> Type). Applicative f => a -> f b -> s -> f t -- | This is a type alias for monomorphic traversals which don't change the -- type of the container (or of the values inside). type Traversal' s a = Traversal s s a a -- | Monadic state transformer. -- -- Maps an old state to a new state inside a state monad. The old state -- is thrown away. -- --
-- Main> :t modify ((+1) :: Int -> Int) -- modify (...) :: (MonadState Int a) => a () ---- -- This says that modify (+1) acts over any Monad that is a -- member of the MonadState class, with an Int state. modify :: MonadState s m => (s -> s) -> m () -- | Retrieves a function of the current environment. asks :: MonadReader r m => (r -> a) -> m a -- | The reader monad transformer, which adds a read-only environment to -- the given monad. -- -- The return function ignores the environment, while -- >>= passes the inherited environment to both -- subcomputations. newtype ReaderT r (m :: Type -> Type) a ReaderT :: (r -> m a) -> ReaderT r (m :: Type -> Type) a [runReaderT] :: ReaderT r (m :: Type -> Type) a -> r -> m a -- | preuse is (^?) (or preview) which implicitly -- operates on the state – it takes the state and applies a traversal (or -- fold) to it to extract the 1st element the traversal points at. -- --
-- preuse l = gets (preview l) --preuse :: MonadState s m => Getting (First a) s a -> m (Maybe a) -- | use is (^.) (or view) which implicitly operates -- on the state; for instance, if your state is a record containing a -- field foo, you can write -- --
-- x <- use foo ---- -- to extract foo from the state. In other words, use is -- the same as gets, but for getters instead of functions. -- -- The implementation of use is straightforward: -- --
-- use l = gets (view l) ---- -- If you need to extract something with a fold or traversal, you need -- preuse. use :: MonadState s m => Getting a s a -> m a -- | preview is a synonym for (^?), generalised for -- MonadReader (just like view, which is a synonym for -- (^.)). -- --
-- >>> preview each [1..5] -- Just 1 --preview :: MonadReader s m => Getting (First a) s a -> m (Maybe a) -- | view is a synonym for (^.), generalised for -- MonadReader (we are able to use it instead of (^.) since -- functions are instances of the MonadReader class): -- --
-- >>> view _1 (1, 2) -- 1 ---- -- When you're using Reader for config and your config type has -- lenses generated for it, most of the time you'll be using view -- instead of asks: -- --
-- doSomething :: (MonadReader Config m) => m Int -- doSomething = do -- thingy <- view setting1 -- same as “asks (^. setting1)” -- anotherThingy <- view setting2 -- ... --view :: MonadReader s m => Getting a s a -> m a -- | Map several constraints over several variables. -- --
-- f :: Each [Show, Read] [a, b] => a -> b -> String -- = -- f :: (Show a, Show b, Read a, Read b) => a -> b -> String ---- -- To specify list with single constraint / variable, don't forget to -- prefix it with ': -- --
-- f :: Each '[Show] [a, b] => a -> b -> String --type family Each (c :: [k -> Constraint]) (as :: [k]) -- | Shorter alias for pure (). -- --
-- >>> pass :: Maybe () -- Just () --pass :: Applicative f => f () -- | Stricter version of $ operator. Default Prelude defines this at -- the toplevel module, so we do as well. -- --
-- >>> const 3 $ Prelude.undefined -- 3 -- -- >>> const 3 $! Prelude.undefined -- *** Exception: Prelude.undefined -- ... --($!) :: (a -> b) -> a -> b infixr 0 $! -- | map generalized to Functor. -- --
-- >>> map not (Just True) -- Just False -- -- >>> map not [True,False,True,True] -- [False,True,False,False] --map :: Functor f => (a -> b) -> f a -> f b -- | Alias for fmap . fmap. Convenient to work with two nested -- Functors. -- --
-- >>> negate <<$>> Just [1,2,3] -- Just [-1,-2,-3] --(<<$>>) :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b) infixl 4 <<$>> -- | Lifted to MonadIO version of newEmptyMVar. newEmptyMVar :: MonadIO m => m (MVar a) -- | Lifted to MonadIO version of newMVar. newMVar :: MonadIO m => a -> m (MVar a) -- | Lifted to MonadIO version of putMVar. putMVar :: MonadIO m => MVar a -> a -> m () -- | Lifted to MonadIO version of readMVar. readMVar :: MonadIO m => MVar a -> m a -- | Lifted to MonadIO version of swapMVar. swapMVar :: MonadIO m => MVar a -> a -> m a -- | Lifted to MonadIO version of takeMVar. takeMVar :: MonadIO m => MVar a -> m a -- | Lifted to MonadIO version of tryPutMVar. tryPutMVar :: MonadIO m => MVar a -> a -> m Bool -- | Lifted to MonadIO version of tryReadMVar. tryReadMVar :: MonadIO m => MVar a -> m (Maybe a) -- | Lifted to MonadIO version of tryTakeMVar. tryTakeMVar :: MonadIO m => MVar a -> m (Maybe a) -- | Lifted to MonadIO version of atomically. atomically :: MonadIO m => STM a -> m a -- | Lifted to MonadIO version of newTVarIO. newTVarIO :: MonadIO m => a -> m (TVar a) -- | Lifted to MonadIO version of readTVarIO. readTVarIO :: MonadIO m => TVar a -> m a -- | Lifted version of exitWith. exitWith :: MonadIO m => ExitCode -> m a -- | Lifted version of exitFailure. exitFailure :: MonadIO m => m a -- | Lifted version of exitSuccess. exitSuccess :: MonadIO m => m a -- | Lifted version of die. die is available since base-4.8, -- but it's more convenient to redefine it instead of using CPP. die :: MonadIO m => String -> m a -- | Lifted version of appendFile. appendFile :: MonadIO m => FilePath -> Text -> m () -- | Lifted version of getLine. getLine :: MonadIO m => m Text -- | Lifted version of openFile. -- -- See also withFile for more information. openFile :: MonadIO m => FilePath -> IOMode -> m Handle -- | Close a file handle -- -- See also withFile for more information. hClose :: MonadIO m => Handle -> m () -- | Opens a file, manipulates it with the provided function and closes the -- handle before returning. The Handle can be written to using the -- hPutStr and hPutStrLn functions. -- -- withFile is essentially the bracket pattern, specialized -- to files. This should be preferred over openFile + -- hClose as it properly deals with (asynchronous) exceptions. In -- cases where withFile is insufficient, for instance because the -- it is not statically known when manipulating the Handle has -- finished, one should consider other safe paradigms for resource usage, -- such as the ResourceT transformer from the resourcet -- package, before resorting to openFile and hClose. withFile :: (MonadIO m, MonadMask m) => FilePath -> IOMode -> (Handle -> m a) -> m a -- | Lifted version of newIORef. newIORef :: MonadIO m => a -> m (IORef a) -- | Lifted version of readIORef. readIORef :: MonadIO m => IORef a -> m a -- | Lifted version of writeIORef. writeIORef :: MonadIO m => IORef a -> a -> m () -- | Lifted version of modifyIORef. modifyIORef :: MonadIO m => IORef a -> (a -> a) -> m () -- | Lifted version of modifyIORef'. modifyIORef' :: MonadIO m => IORef a -> (a -> a) -> m () -- | Lifted version of atomicModifyIORef. atomicModifyIORef :: MonadIO m => IORef a -> (a -> (a, b)) -> m b -- | Lifted version of atomicModifyIORef'. atomicModifyIORef' :: MonadIO m => IORef a -> (a -> (a, b)) -> m b -- | Lifted version of atomicWriteIORef. atomicWriteIORef :: MonadIO m => IORef a -> a -> m () -- | Specialized version of for_ for Maybe. It's used for -- code readability. Also helps to avoid space leaks: Foldable.mapM_ -- space leak. -- --
-- >>> whenJust Nothing $ \b -> print (not b) -- -- >>> whenJust (Just True) $ \b -> print (not b) -- False --whenJust :: Applicative f => Maybe a -> (a -> f ()) -> f () -- | Monadic version of whenJust. whenJustM :: Monad m => m (Maybe a) -> (a -> m ()) -> m () -- | Performs default Applicative action if Nothing is given. -- Otherwise returns content of Just pured to Applicative. -- --
-- >>> whenNothing Nothing [True, False] -- [True,False] -- -- >>> whenNothing (Just True) [True, False] -- [True] --whenNothing :: Applicative f => Maybe a -> f a -> f a -- | Performs default Applicative action if Nothing is given. -- Do nothing for Just. Convenient for discarding Just -- content. -- --
-- >>> whenNothing_ Nothing $ putTextLn "Nothing!" -- Nothing! -- -- >>> whenNothing_ (Just True) $ putTextLn "Nothing!" --whenNothing_ :: Applicative f => Maybe a -> f () -> f () -- | Monadic version of whenNothing. whenNothingM :: Monad m => m (Maybe a) -> m a -> m a -- | Monadic version of whenNothingM_. whenNothingM_ :: Monad m => m (Maybe a) -> m () -> m () -- | Extracts value from Left or return given default value. -- --
-- >>> fromLeft 0 (Left 3) -- 3 -- -- >>> fromLeft 0 (Right 5) -- 0 --fromLeft :: a -> Either a b -> a -- | Extracts value from Right or return given default value. -- --
-- >>> fromRight 0 (Left 3) -- 0 -- -- >>> fromRight 0 (Right 5) -- 5 --fromRight :: b -> Either a b -> b -- | Maps left part of Either to Maybe. -- --
-- >>> leftToMaybe (Left True) -- Just True -- -- >>> leftToMaybe (Right "aba") -- Nothing --leftToMaybe :: Either l r -> Maybe l -- | Maps right part of Either to Maybe. -- --
-- >>> rightToMaybe (Left True) -- Nothing -- -- >>> rightToMaybe (Right "aba") -- Just "aba" --rightToMaybe :: Either l r -> Maybe r -- | Maps Maybe to Either wrapping default value into -- Left. -- --
-- >>> maybeToRight True (Just "aba") -- Right "aba" -- -- >>> maybeToRight True Nothing -- Left True --maybeToRight :: l -> Maybe r -> Either l r -- | Maps Maybe to Either wrapping default value into -- Right. -- --
-- >>> maybeToLeft True (Just "aba") -- Left "aba" -- -- >>> maybeToLeft True Nothing -- Right True --maybeToLeft :: r -> Maybe l -> Either l r -- | Monadic version of whenLeft. whenLeftM :: Monad m => m (Either l r) -> (l -> m ()) -> m () -- | Monadic version of whenRight. whenRightM :: Monad m => m (Either l r) -> (r -> m ()) -> m () -- | Shorter and more readable alias for flip runReaderT. usingReaderT :: r -> ReaderT r m a -> m a -- | Shorter and more readable alias for flip runReader. usingReader :: r -> Reader r a -> a -- | Shorter and more readable alias for flip runStateT. usingStateT :: s -> StateT s m a -> m (a, s) -- | Shorter and more readable alias for flip runState. usingState :: s -> State s a -> (a, s) -- | Alias for flip evalStateT. It's not shorter but sometimes -- more readable. Done by analogy with using* functions family. evaluatingStateT :: Functor f => s -> StateT s f a -> f a -- | Alias for flip evalState. It's not shorter but sometimes more -- readable. Done by analogy with using* functions family. evaluatingState :: s -> State s a -> a -- | Alias for flip execStateT. It's not shorter but sometimes -- more readable. Done by analogy with using* functions family. executingStateT :: Functor f => s -> StateT s f a -> f s -- | Alias for flip execState. It's not shorter but sometimes more -- readable. Done by analogy with using* functions family. executingState :: s -> State s a -> s -- | Extracts Monoid value from Maybe returning mempty -- if Nothing. -- --
-- >>> maybeToMonoid (Just [1,2,3] :: Maybe [Int]) -- [1,2,3] -- -- >>> maybeToMonoid (Nothing :: Maybe [Int]) -- [] --maybeToMonoid :: Monoid m => Maybe m -> m -- | Type class for types that can be created from one element. -- singleton is lone name for this function. Also constructions -- of different type differ: :[] for lists, two arguments for -- Maps. Also some data types are monomorphic. -- --
-- >>> one True :: [Bool] -- [True] -- -- >>> one 'a' :: Text -- "a" -- -- >>> one (3, "hello") :: HashMap Int String -- fromList [(3,"hello")] --class One x where { type family OneItem x; } -- | Create a list, map, Text, etc from a single element. one :: One x => OneItem x -> x type family OneItem x -- | Very similar to Foldable but also allows instances for -- monomorphic types like Text but forbids instances for -- Maybe and similar. This class is used as a replacement for -- Foldable type class. It solves the following problems: -- --
-- >>> toList @Text "aba" -- "aba" -- -- >>> :t toList @Text "aba" -- toList @Text "aba" :: [Char] --toList :: Container t => t -> [Element t] -- | Checks whether container is empty. -- --
-- >>> null @Text "" -- True -- -- >>> null @Text "aba" -- False --null :: Container t => t -> Bool foldr :: Container t => (Element t -> b -> b) -> b -> t -> b foldl :: Container t => (b -> Element t -> b) -> b -> t -> b foldl' :: Container t => (b -> Element t -> b) -> b -> t -> b length :: Container t => t -> Int elem :: Container t => Element t -> t -> Bool maximum :: Container t => t -> Element t minimum :: Container t => t -> Element t foldMap :: (Container t, Monoid m) => (Element t -> m) -> t -> m fold :: Container t => t -> Element t foldr' :: Container t => (Element t -> b -> b) -> b -> t -> b foldr1 :: Container t => (Element t -> Element t -> Element t) -> t -> Element t foldl1 :: Container t => (Element t -> Element t -> Element t) -> t -> Element t notElem :: Container t => Element t -> t -> Bool all :: Container t => (Element t -> Bool) -> t -> Bool any :: Container t => (Element t -> Bool) -> t -> Bool find :: Container t => (Element t -> Bool) -> t -> Maybe (Element t) safeHead :: Container t => t -> Maybe (Element t) -- | Type of element for some container. Implemented as an asscociated type -- family because some containers are monomorphic over element type (like -- Text, IntSet, etc.) so we can't implement nice interface -- using old higher-kinded types approach. Implementing this as an -- associated type family instead of top-level family gives you more -- control over element types. type family Element t -- | Type class for data types that can be converted to List of Pairs. You -- can define ToPairs by just defining toPairs function. -- -- But the following laws should be met: -- --
-- toPairs m ≡ zip (keys m) (elems m) -- keys ≡ map fst . toPairs -- elems ≡ map snd . toPairs --class ToPairs t -- | Converts the structure to the list of the key-value pairs. -- >>> toPairs (HashMap.fromList [(a, "xxx"), -- (b, "yyy")]) [(a,"xxx"),(b,"yyy")] toPairs :: ToPairs t => t -> [(Key t, Val t)] -- | Converts the structure to the list of the keys. -- --
-- >>> keys (HashMap.fromList [('a', "xxx"), ('b', "yyy")])
-- "ab"
--
keys :: ToPairs t => t -> [Key t]
-- | Converts the structure to the list of the values.
--
--
-- >>> elems (HashMap.fromList [('a', "xxx"), ('b', "yyy")])
-- ["xxx","yyy"]
--
elems :: ToPairs t => t -> [Val t]
-- | Similar to foldl' but takes a function with its arguments
-- flipped.
--
-- -- >>> flipfoldl' (/) 5 [2,3] :: Rational -- 15 % 2 --flipfoldl' :: (Container t, Element t ~ a) => (a -> b -> b) -> b -> t -> b -- | Stricter version of sum. -- --
-- >>> sum [1..10] -- 55 -- -- >>> sum (Just 3) -- ... -- • Do not use 'Foldable' methods on Maybe -- Suggestions: -- Instead of -- for_ :: (Foldable t, Applicative f) => t a -> (a -> f b) -> f () -- use -- whenJust :: Applicative f => Maybe a -> (a -> f ()) -> f () -- whenRight :: Applicative f => Either l r -> (r -> f ()) -> f () -- ... -- Instead of -- fold :: (Foldable t, Monoid m) => t m -> m -- use -- maybeToMonoid :: Monoid m => Maybe m -> m -- ... --sum :: (Container t, Num (Element t)) => t -> Element t -- | Stricter version of product. -- --
-- >>> product [1..10] -- 3628800 -- -- >>> product (Right 3) -- ... -- • Do not use 'Foldable' methods on Either -- Suggestions: -- Instead of -- for_ :: (Foldable t, Applicative f) => t a -> (a -> f b) -> f () -- use -- whenJust :: Applicative f => Maybe a -> (a -> f ()) -> f () -- whenRight :: Applicative f => Either l r -> (r -> f ()) -> f () -- ... -- Instead of -- fold :: (Foldable t, Monoid m) => t m -> m -- use -- maybeToMonoid :: Monoid m => Maybe m -> m -- ... --product :: (Container t, Num (Element t)) => t -> Element t -- | Constrained to Container version of traverse_. -- --
-- >>> traverse_ putTextLn ["foo", "bar"] -- foo -- bar --traverse_ :: (Container t, Applicative f) => (Element t -> f b) -> t -> f () -- | Constrained to Container version of for_. -- --
-- >>> for_ [1 .. 5 :: Int] $ \i -> when (even i) (print i) -- 2 -- 4 --for_ :: (Container t, Applicative f) => t -> (Element t -> f b) -> f () -- | Constrained to Container version of mapM_. -- --
-- >>> mapM_ print [True, False] -- True -- False --mapM_ :: (Container t, Monad m) => (Element t -> m b) -> t -> m () -- | Constrained to Container version of forM_. -- --
-- >>> forM_ [True, False] print -- True -- False --forM_ :: (Container t, Monad m) => t -> (Element t -> m b) -> m () -- | Constrained to Container version of sequenceA_. -- --
-- >>> sequenceA_ [putTextLn "foo", print True] -- foo -- True --sequenceA_ :: (Container t, Applicative f, Element t ~ f a) => t -> f () -- | Constrained to Container version of sequence_. -- --
-- >>> sequence_ [putTextLn "foo", print True] -- foo -- True --sequence_ :: (Container t, Monad m, Element t ~ m a) => t -> m () -- | Constrained to Container version of asum. -- --
-- >>> asum [Nothing, Just [False, True], Nothing, Just [True]] -- Just [False,True] --asum :: (Container t, Alternative f, Element t ~ f a) => t -> f a -- | Lifting bind into a monad. Generalized version of concatMap -- that works with a monadic predicate. Old and simpler specialized to -- list version had next type: -- --
-- concatMapM :: Monad m => (a -> m [b]) -> [a] -> m [b] ---- -- Side note: previously it had type -- --
-- concatMapM :: (Applicative q, Monad m, Traversable m) -- => (a -> q (m b)) -> m a -> q (m b) ---- -- Such signature didn't allow to use this function when traversed -- container type and type of returned by function-argument differed. Now -- you can use it like e.g. -- --
-- concatMapM readFile files >>= putTextLn --concatMapM :: (Applicative f, Monoid m, Container (l m), Element (l m) ~ m, Traversable l) => (a -> f m) -> l a -> f m -- | Like concatMapM, but has its arguments flipped, so can be used -- instead of the common fmap concat $ forM pattern. concatForM :: (Applicative f, Monoid m, Container (l m), Element (l m) ~ m, Traversable l) => l a -> (a -> f m) -> f m -- | Monadic and constrained to Container version of and. -- --
-- >>> andM [Just True, Just False] -- Just False -- -- >>> andM [Just True] -- Just True -- -- >>> andM [Just True, Just False, Nothing] -- Just False -- -- >>> andM [Just True, Nothing] -- Nothing -- -- >>> andM [putTextLn "1" >> pure True, putTextLn "2" >> pure False, putTextLn "3" >> pure True] -- 1 -- 2 -- False --andM :: (Container f, Element f ~ m Bool, Monad m) => f -> m Bool -- | Monadic and constrained to Container version of or. -- --
-- >>> orM [Just True, Just False] -- Just True -- -- >>> orM [Just True, Nothing] -- Just True -- -- >>> orM [Nothing, Just True] -- Nothing --orM :: (Container f, Element f ~ m Bool, Monad m) => f -> m Bool -- | Monadic and constrained to Container version of all. -- --
-- >>> allM (readMaybe >=> pure . even) ["6", "10"] -- Just True -- -- >>> allM (readMaybe >=> pure . even) ["5", "aba"] -- Just False -- -- >>> allM (readMaybe >=> pure . even) ["aba", "10"] -- Nothing --allM :: (Container f, Monad m) => (Element f -> m Bool) -> f -> m Bool -- | Monadic and constrained to Container version of any. -- --
-- >>> anyM (readMaybe >=> pure . even) ["5", "10"] -- Just True -- -- >>> anyM (readMaybe >=> pure . even) ["10", "aba"] -- Just True -- -- >>> anyM (readMaybe >=> pure . even) ["aba", "10"] -- Nothing --anyM :: (Container f, Monad m) => (Element f -> m Bool) -> f -> m Bool -- | Destructuring list into its head and tail if possible. This function -- is total. -- --
-- >>> uncons [] -- Nothing -- -- >>> uncons [1..5] -- Just (1,[2,3,4,5]) -- -- >>> uncons (5 : [1..5]) >>= \(f, l) -> pure $ f == length l -- Just True --uncons :: [a] -> Maybe (a, [a]) -- | Performs given action over NonEmpty list if given list is non -- empty. -- --
-- >>> whenNotNull [] $ \(b :| _) -> print (not b) -- -- >>> whenNotNull [False,True] $ \(b :| _) -> print (not b) -- True --whenNotNull :: Applicative f => [a] -> (NonEmpty a -> f ()) -> f () -- | Monadic version of whenNotNull. whenNotNullM :: Monad m => m [a] -> (NonEmpty a -> m ()) -> m () -- | Type that represents exceptions used in cases when a particular -- codepath is not meant to be ever executed, but happens to be executed -- anyway. data Bug Bug :: SomeException -> CallStack -> Bug -- | Pattern synonym to easy pattern matching on exceptions. So intead of -- writing something like this: -- --
-- isNonCriticalExc e
-- | Just (_ :: NodeAttackedError) <- fromException e = True
-- | Just DialogUnexpected{} <- fromException e = True
-- | otherwise = False
--
--
-- you can use Exc pattern synonym:
--
--
-- isNonCriticalExc = case
-- Exc (_ :: NodeAttackedError) -> True -- matching all exceptions of type NodeAttackedError
-- Exc DialogUnexpected{} -> True
-- _ -> False
--
--
-- This pattern is bidirectional. You can use Exc e instead of
-- toException e.
pattern Exc :: Exception e => e -> SomeException
-- | Generate a pure value which, when forced, will synchronously throw the
-- exception wrapped into Bug data type.
bug :: (HasCallStack, Exception e) => e -> a
-- | Throws error for Maybe if Nothing is given. Operates
-- over MonadError.
note :: MonadError e m => e -> Maybe a -> m a
-- | Lifted alias for evaluate with clearer name.
evaluateWHNF :: MonadIO m => a -> m a
-- | Like evaluateWNHF but discards value.
evaluateWHNF_ :: MonadIO m => a -> m ()
-- | Alias for evaluateWHNF . force with clearer name.
evaluateNF :: (NFData a, MonadIO m) => a -> m a
-- | Alias for evaluateWHNF . rnf. Similar to evaluateNF
-- but discards resulting value.
evaluateNF_ :: (NFData a, MonadIO m) => a -> m ()
-- | Monadic version of when.
--
--
-- >>> whenM (pure False) $ putTextLn "No text :("
--
-- >>> whenM (pure True) $ putTextLn "Yes text :)"
-- Yes text :)
--
-- >>> whenM (Just True) (pure ())
-- Just ()
--
-- >>> whenM (Just False) (pure ())
-- Just ()
--
-- >>> whenM Nothing (pure ())
-- Nothing
--
whenM :: Monad m => m Bool -> m () -> m ()
-- | Monadic version of unless.
--
--
-- >>> unlessM (pure False) $ putTextLn "No text :("
-- No text :(
--
-- >>> unlessM (pure True) $ putTextLn "Yes text :)"
--
unlessM :: Monad m => m Bool -> m () -> m ()
-- | Monadic version of if-then-else.
--
-- -- >>> ifM (pure True) (putTextLn "True text") (putTextLn "False text") -- True text --ifM :: Monad m => m Bool -> m a -> m a -> m a -- | Monadic version of guard. Occasionally useful. Here some -- complex but real-life example: -- --
-- findSomePath :: IO (Maybe FilePath) -- -- somePath :: MaybeT IO FilePath -- somePath = do -- path <- MaybeT findSomePath -- guardM $ liftIO $ doesDirectoryExist path -- return path --guardM :: MonadPlus m => m Bool -> m () -- | Like nub but runs in O(n * log n) time and requires -- Ord. -- --
-- >>> ordNub [3, 3, 3, 2, 2, -1, 1] -- [3,2,-1,1] --ordNub :: Ord a => [a] -> [a] -- | Like nub but runs in O(n * log_16(n)) time and -- requires Hashable. -- --
-- >>> hashNub [3, 3, 3, 2, 2, -1, 1] -- [3,2,-1,1] --hashNub :: (Eq a, Hashable a) => [a] -> [a] -- | Like ordNub but also sorts a list. -- --
-- >>> sortNub [3, 3, 3, 2, 2, -1, 1] -- [-1,1,2,3] --sortNub :: Ord a => [a] -> [a] -- | Like hashNub but has better performance and also doesn't save -- the order. -- --
-- >>> unstableNub [3, 3, 3, 2, 2, -1, 1] -- [1,2,3,-1] --unstableNub :: (Eq a, Hashable a) => [a] -> [a] -- | Support class to overload writing of string like values. class Print a -- | Write a string like value a to a supplied Handle. hPutStr :: (Print a, MonadIO m) => Handle -> a -> m () -- | Write a string like value a to a supplied Handle, -- appending a newline character. hPutStrLn :: (Print a, MonadIO m) => Handle -> a -> m () -- | Write a string like value to stdout/. putStr :: (Print a, MonadIO m) => a -> m () -- | Write a string like value to stdout appending a newline -- character. putStrLn :: (Print a, MonadIO m) => a -> m () -- | Lifted version of print. print :: forall a m. (MonadIO m, Show a) => a -> m () -- | Lifted version of hPrint hPrint :: (MonadIO m, Show a) => Handle -> a -> m () -- | Specialized to Text version of putStr or forcing type -- inference. putText :: MonadIO m => Text -> m () -- | Specialized to Text version of putStrLn or forcing type -- inference. putTextLn :: MonadIO m => Text -> m () -- | Specialized to Text version of putStr or forcing type -- inference. putLText :: MonadIO m => Text -> m () -- | Specialized to Text version of putStrLn or forcing type -- inference. putLTextLn :: MonadIO m => Text -> m () -- | Similar to undefined but data type. data Undefined Undefined :: Undefined -- | Version of trace that leaves a warning and takes Text. trace :: Text -> a -> a -- | Version of traceShow that leaves a warning. traceShow :: Show a => a -> b -> b -- | Version of traceShowId that leaves a warning. traceShowId :: Show a => a -> a -- | Version of traceId that leaves a warning. Useful to tag printed -- data, for instance: -- --
-- traceIdWith (x -> "My data: " <> show x) (veryLargeExpression) ---- -- This is especially useful with custom formatters: -- --
-- traceIdWith (x -> "My data: " <> pretty x) (veryLargeExpression) --traceIdWith :: (a -> Text) -> a -> a -- | Version of traceShowId that leaves a warning. Useful to tag -- printed data, for instance: -- --
-- traceShowIdWith ("My data: ", ) (veryLargeExpression)
--
traceShowIdWith :: Show s => (a -> s) -> a -> a
-- | Version of traceShowM that leaves a warning.
traceShowM :: (Show a, Monad m) => a -> m ()
-- | Version of traceM that leaves a warning and takes Text.
traceM :: Monad m => Text -> m ()
-- | Version of traceId that leaves a warning.
traceId :: Text -> Text
-- | Type class for converting other strings to String.
class ToString a
toString :: ToString a => a -> String
-- | Type class for converting other strings to Text.
class ToLText a
toLText :: ToLText a => a -> Text
-- | Type class for converting other strings to Text.
class ToText a
toText :: ToText a => a -> Text
-- | Type class for conversion to utf8 representation of text.
class ConvertUtf8 a b
-- | Encode as utf8 string (usually ByteString).
--
-- -- >>> encodeUtf8 @Text @ByteString "патак" -- "\208\191\208\176\209\130\208\176\208\186" --encodeUtf8 :: ConvertUtf8 a b => a -> b -- | Decode from utf8 string. -- --
-- >>> decodeUtf8 @Text @ByteString "\208\191\208\176\209\130\208\176\208\186" -- "\1087\1072\1090\1072\1082" -- -- >>> putStrLn $ decodeUtf8 @Text @ByteString "\208\191\208\176\209\130\208\176\208\186" -- патак --decodeUtf8 :: ConvertUtf8 a b => b -> a -- | Decode as utf8 string but returning execption if byte sequence is -- malformed. -- --
-- >>> decodeUtf8 @Text @ByteString "\208\208\176\209\130\208\176\208\186" -- "\65533\1072\1090\1072\1082" ---- --
-- >>> decodeUtf8Strict @Text @ByteString "\208\208\176\209\130\208\176\208\186" -- Left Cannot decode byte '\xd0': Data.Text.Internal.Encoding.decodeUtf8: Invalid UTF-8 stream --decodeUtf8Strict :: ConvertUtf8 a b => b -> Either UnicodeException a -- | Type synonym for ByteString. type LByteString = ByteString -- | Type synonym for Text. type LText = Text -- | Polymorhpic version of readEither. -- --
-- >>> readEither @Text @Int "123" -- Right 123 -- -- >>> readEither @Text @Int "aa" -- Left "Prelude.read: no parse" --readEither :: (ToString a, Read b) => a -> Either Text b -- | Generalized version of show. show :: forall b a. (Show a, IsString b) => a -> b -- | Map several constraints over a single variable. Note, that With a -- b ≡ Each a '[b] -- --
-- a :: With [Show, Read] a => a -> a -- = -- a :: (Show a, Read a) => a -> a --type With (a :: [k -> Constraint]) (b :: k) = a <+> b -- | This type class allows to implement variadic composition operator. class SuperComposition a b c | a b -> c -- | Allows to apply function to result of another function with multiple -- arguments. -- --
-- >>> (show ... (+)) 1 2 -- "3" -- -- >>> show ... 5 -- "5" -- -- >>> (null ... zip5) [1] [2] [3] [] [5] -- True ---- -- Inspired by -- http://stackoverflow.com/questions/9656797/variadic-compose-function. -- --
execStateT m s = liftM snd -- (runStateT m s)
evalStateT m s = liftM fst -- (runStateT m s)
-- (a, b) <- if flag -- then do -- anotherFlag <- newVar True -- return (5 +. var, anotherFlag ||. True) -- else return (0, anotherVar) ---- -- is a valid construction. Pay attention to the fact that 5 +. -- var has the type Expr Integer, but 0 is just an -- Integer and anotherFlag ||. True has type Expr -- Bool, but anotherVar has type Var Bool; -- and this code will compile anyway. This is done intentionally to avoid -- the burden of manually converting values to expressions (or -- variables). So you can write the same constructions as in a regular -- language. module Indigo.Backend.Scope -- | To avoid overlapping instances we need to somehow distinguish single -- values from tuples, because the instances: -- --
-- instance Something a -- instance Something (a, b) ---- -- overlap and adding {-# OVERLAPPING #-} doesn't rescue in some -- cases, especially for type families defined in Something. data BranchRetKind -- | If value is unit (don't return anything) Unit :: BranchRetKind -- | If it's a single value (not tuple) SingleVal :: BranchRetKind -- | If it's tuple (we don't care how many elements are in) Tuple :: BranchRetKind type ScopeCodeGen ret = ScopeCodeGen' (ClassifyReturnValue ret) ret -- | Type class which unions all related management of computations in a -- scope, like in if branch, in case body, etc. -- -- Particularly, it takes care of the computation of expressions -- returning from a scope to leave it safely. Basically, this type class -- encapsulates the generation of Lorentz code that looks like: -- --
-- branch_code # -- -- we get some arbitrary type of a stack here, lets call it xs -- compute_returning_expressions # -- -- we get type of stack [e1, e2, ... ek] ++ xs -- cleanup_xs_to_inp -- -- we get [e1, e2, e3, ..., ek] ++ inp --class ReturnableValue' retKind ret => ScopeCodeGen' (retKind :: BranchRetKind) (ret :: Type) -- | Produces an Indigo computation that puts on the stack the evaluated -- returned expressions from the leaving scope. compileScopeReturn' :: ScopeCodeGen' retKind ret => ret -> IndigoState xs (RetOutStack' retKind ret ++ xs) -- | Drop the stack cells that were produced in the leaving scope, apart -- from ones corresponding to the returning expressions. liftClear' :: ScopeCodeGen' retKind ret => (xs :-> inp) -> (RetOutStack' retKind ret ++ xs) :-> (RetOutStack' retKind ret ++ inp) -- | Generate gcClear for the whole statement genGcClear' :: ScopeCodeGen' retKind ret => (RetOutStack' retKind ret ++ inp) :-> inp type ReturnableValue ret = ReturnableValue' (ClassifyReturnValue ret) ret -- | Class for values that can be returned from Indigo statements. They -- include () and tuples. class ReturnableValue' (retKind :: BranchRetKind) (ret :: Type) where { -- | Type family reflecting the top elements of stack produced by a -- statement returning the value. type family RetOutStack' retKind ret :: [Type]; -- | Type family reflecting the returning value from a statement. type family RetVars' retKind ret :: Type; -- | Tuple looking like (Expr x, Expr y, ..) that corresponds to -- expressions returning from the scope. 'RetVars'' and 'RetExprs'' are -- twin types because the former just adds Var over each -- expression of the latter. type family RetExprs' retKind ret :: Type; } -- | Allocate variables referring to result of the statement. Requires an -- allocator operating in a Monad. allocateVars' :: (ReturnableValue' retKind ret, Monad m) => (forall (x :: Type). m (Var x)) -> m (RetVars' retKind ret) -- | Push the variables referring to the result of the statement on top of -- the stack of the given StackVars. assignVars' :: ReturnableValue' retKind ret => RetVars' retKind ret -> StackVars inp -> StackVars (RetOutStack' retKind ret ++ inp) -- | Pretty printing of statements like "var := statement" prettyAssign' :: ReturnableValue' retKind ret => RetVars' retKind ret -> Text -> Text -- | Prettify ret value prettyRet' :: ReturnableValue' retKind ret => ret -> Text type RetOutStack ret = RetOutStack' (ClassifyReturnValue ret) ret type RetVars ret = RetVars' (ClassifyReturnValue ret) ret type RetExprs ret = RetExprs' (ClassifyReturnValue ret) ret -- | This type family returns a promoted value of type BranchRetKind -- or causes a compilation error if a tuple with too many elements is -- used. type family ClassifyReturnValue (ret :: Type) -- | Specific version of 'liftClear'' liftClear :: forall ret inp xs. ScopeCodeGen ret => (xs :-> inp) -> (RetOutStack ret ++ xs) :-> (RetOutStack ret ++ inp) -- | Concatenate a scoped code, generation of returning expressions, and -- clean up of redundant cells from the stack. compileScope :: forall ret inp xs. ScopeCodeGen ret => (StackVars xs -> MetaData xs) -> GenCode inp xs -> ret -> inp :-> (RetOutStack ret ++ inp) -- | Specific version of 'allocateVars'' allocateVars :: forall ret m. (ReturnableValue ret, Monad m) => (forall (x :: Type). m (Var x)) -> m (RetVars ret) -- | Push variables in the StackVars, referring to the generated -- expressions, and generate gcClear for the whole statement. finalizeStatement :: forall ret inp. ScopeCodeGen ret => StackVars inp -> RetVars ret -> (inp :-> (RetOutStack ret ++ inp)) -> GenCode inp (RetOutStack ret ++ inp) prettyAssign :: forall ret. ReturnableValue ret => RetVars ret -> Text -> Text condStmtPretty :: forall ret x. ReturnableValue ret => RetVars ret -> Text -> Expr x -> Text prettyRet :: forall ret. ReturnableValue ret => ret -> Text instance Indigo.Backend.Scope.KnownValueExpr single => Indigo.Backend.Scope.ReturnableValue' 'Indigo.Backend.Scope.SingleVal single instance Indigo.Backend.Scope.KnownValueExpr single => Indigo.Backend.Scope.ScopeCodeGen' 'Indigo.Backend.Scope.SingleVal single instance (Indigo.Backend.Scope.KnownValueExpr x, Indigo.Backend.Scope.KnownValueExpr y, Formatting.Buildable.Buildable (Indigo.Backend.Scope.RetVars' 'Indigo.Backend.Scope.Tuple (x, y))) => Indigo.Backend.Scope.ReturnableValue' 'Indigo.Backend.Scope.Tuple (x, y) instance (Indigo.Backend.Scope.KnownValueExpr x, Indigo.Backend.Scope.KnownValueExpr y, Formatting.Buildable.Buildable (Indigo.Backend.Scope.RetVars' 'Indigo.Backend.Scope.Tuple (x, y))) => Indigo.Backend.Scope.ScopeCodeGen' 'Indigo.Backend.Scope.Tuple (x, y) instance (Indigo.Backend.Scope.KnownValueExpr x, Indigo.Backend.Scope.KnownValueExpr y, Indigo.Backend.Scope.KnownValueExpr z, Formatting.Buildable.Buildable (Indigo.Backend.Scope.RetVars' 'Indigo.Backend.Scope.Tuple (x, y, z))) => Indigo.Backend.Scope.ReturnableValue' 'Indigo.Backend.Scope.Tuple (x, y, z) instance (Indigo.Backend.Scope.KnownValueExpr x, Indigo.Backend.Scope.KnownValueExpr y, Indigo.Backend.Scope.KnownValueExpr z, Formatting.Buildable.Buildable (Indigo.Backend.Scope.RetVars' 'Indigo.Backend.Scope.Tuple (x, y, z))) => Indigo.Backend.Scope.ScopeCodeGen' 'Indigo.Backend.Scope.Tuple (x, y, z) instance Indigo.Backend.Scope.ScopeCodeGen' 'Indigo.Backend.Scope.Unit () instance Indigo.Backend.Scope.ReturnableValue' 'Indigo.Backend.Scope.Unit () -- | Backend statements for variable manipulation: assignment, replacement, -- update. module Indigo.Backend.Var -- | Assign the given variable to the value resulting from the given -- expression. assignVar :: forall x inp. KnownValue x => Var x -> Expr x -> IndigoState inp (x : inp) -- | Set the variable to a new value. -- -- If a variable is a cell on the stack, we just compile passed -- expression and replace variable cell on stack. If a variable is -- decomposed, we decompose passed expression and call setVar -- recursively from its fields. -- -- Pay attention that this function takes a next RefId but it doesn't -- return RefId because all allocated variables will be destroyed during -- execution of the function, so allocated ones won't affect next -- allocated ones. setVar :: forall a inp. KnownValue a => RefId -> Var a -> Expr a -> IndigoState inp inp -- | Set the field (direct or indirect) of a complex object. setField :: forall dt fname ftype inp. (IsObject dt, IsObject ftype, HasField dt fname ftype) => RefId -> Var dt -> Label fname -> Expr ftype -> IndigoState inp inp -- | Call binary operator with constant argument to update a variable -- in-place. updateVar :: forall x y inp. (IsObject x, KnownValue y) => RefId -> ([y, x] :-> '[x]) -> Var x -> Expr y -> IndigoState inp inp -- | This module implements the ability to put Indigo computations on the -- stack as a lambda and execute them. module Indigo.Backend.Lambda -- | Describes kind of lambda: pure, modifying storage, effectfull data LambdaKind st arg res extra [PureLambda] :: (ExecuteLambdaPure1C arg res, CreateLambda1CGeneric '[] arg res, Typeable res) => LambdaKind st arg res '[] [StorageLambda] :: (ExecuteLambda1C st arg res, CreateLambda1CGeneric '[st] arg res, Typeable res) => Proxy st -> LambdaKind st arg res '[st] [EffLambda] :: (ExecuteLambdaEff1C st arg res, CreateLambda1CGeneric '[st, Ops] arg res, Typeable res) => Proxy st -> LambdaKind st arg res '[st, Ops] -- | Provide common constraints that are presented in all constructors of -- LambdaKind withLambdaKind :: LambdaKind st arg res extra -> ((ScopeCodeGen res, KnownValue arg, Typeable res, CreateLambda1CGeneric extra arg res) => r) -> r -- | Execute lambda depending on its LambdaKind executeLambda1 :: forall res st arg extra inp. LambdaKind st arg res extra -> RefId -> RetVars res -> LambdaExecutor extra arg res inp -- | Create initial stack vars depending on LambdaKind initLambdaStackVars :: LambdaKind st arg res extra -> Var arg -> StackVars (arg : extra) type CreateLambdaPure1C arg res = CreateLambda1CGeneric '[] arg res type ExecuteLambdaPure1C arg res = ExecuteLambda1CGeneric '[] arg res type CreateLambda1C st arg res = (KnownValue st, CreateLambda1CGeneric '[st] arg res) type ExecuteLambda1C st arg res = (IsObject st, HasStorage st, ExecuteLambda1CGeneric '[st] arg res) type CreateLambdaEff1C st arg res = (KnownValue st, CreateLambda1CGeneric '[st, Ops] arg res) type ExecuteLambdaEff1C st arg res = (HasStorage st, HasSideEffects, IsObject st, ExecuteLambda1CGeneric '[st, Ops] arg res) type CreateLambda1CGeneric extra arg res = (ScopeCodeGen res, KnownValue arg, Typeable extra, ZipInstr (arg : extra), KnownValue (ZippedStack (arg : extra)), KnownValue (ZippedStack (RetOutStack res ++ extra)), ZipInstr (RetOutStack res ++ extra), Typeable (RetOutStack res ++ extra)) -- | Create a lambda, that takes only one argument, from the given -- computation, and return a variable referring to this lambda. createLambda1Generic :: forall arg res extra inp. CreateLambda1CGeneric extra arg res => Var (Lambda1Generic extra arg res) -> res -> StackVars (arg : extra) -> SomeIndigoState (arg : extra) -> IndigoState inp (Lambda1Generic extra arg res : inp) type Lambda1Generic extra arg res = (arg : extra) :-> (RetOutStack res ++ extra) -- | Backend conditional statements of Indigo module Indigo.Backend.Conditional -- | If statement. All variables created inside its branches will be -- released after the execution leaves the scope in which they were -- created. if_ :: forall inp a b. IfConstraint a b => Expr Bool -> SomeIndigoState inp -> a -> SomeIndigoState inp -> b -> RetVars a -> IndigoState inp (RetOutStack a ++ inp) -- | If-statement that works like case for Maybe. ifSome :: forall inp x a b. (IfConstraint a b, KnownValue x) => Expr (Maybe x) -> Var x -> SomeIndigoState (x : inp) -> a -> SomeIndigoState inp -> b -> RetVars a -> IndigoState inp (RetOutStack a ++ inp) -- | If which works like case for Either. ifRight :: forall inp r l a b. (IfConstraint a b, KnownValue r, KnownValue l) => Expr (Either l r) -> Var r -> SomeIndigoState (r : inp) -> a -> Var l -> SomeIndigoState (l : inp) -> b -> RetVars a -> IndigoState inp (RetOutStack a ++ inp) -- | If which works like uncons for lists. ifCons :: forall inp x a b. (IfConstraint a b, KnownValue x) => Expr (List x) -> Var x -> Var (List x) -> SomeIndigoState (x : (List x : inp)) -> a -> SomeIndigoState inp -> b -> RetVars a -> IndigoState inp (RetOutStack a ++ inp) type IfConstraint a b = (ScopeCodeGen a, ScopeCodeGen b, CompareBranchesResults (RetExprs a) (RetExprs b), RetVars a ~ RetVars b, RetOutStack a ~ RetOutStack b) -- | Backend machinery for cases. module Indigo.Backend.Case -- | A case statement for indigo. See examples for a sample usage. caseRec :: forall dt inp ret clauses. CaseCommon dt ret clauses => Expr dt -> clauses -> RetVars ret -> IndigoState inp (RetOutStack ret ++ inp) -- | case_ for pattern-matching on parameter. entryCaseRec :: forall dt entrypointKind inp ret clauses. (CaseCommon dt ret clauses, DocumentEntrypoints entrypointKind dt) => Proxy entrypointKind -> Expr dt -> clauses -> RetVars ret -> IndigoState inp (RetOutStack ret ++ inp) -- | entryCase_ for contracts with flat parameter. entryCaseSimpleRec :: forall dt inp ret clauses. (CaseCommon dt ret clauses, DocumentEntrypoints PlainEntrypointsKind dt, NiceParameterFull dt, RequireFlatParamEps dt) => Expr dt -> clauses -> RetVars ret -> IndigoState inp (RetOutStack ret ++ inp) -- | This type is analogous to the CaseClauseL type but instead of -- wrapping a Lorentz instruction, this wraps an Indigo value with the -- same input/output types. data IndigoCaseClauseL ret (param :: CaseClauseParam) data IndigoClause x ret [IndigoClause] :: (KnownValue x, ScopeCodeGen retBr, ret ~ RetExprs retBr, RetOutStack ret ~ RetOutStack retBr) => Var x -> (forall inp. SomeIndigoState (x : inp)) -> retBr -> IndigoClause x ret -- | This constraint is shared by all case* functions. Including -- some outside this module. type CaseCommonF f dt ret clauses = (InstrCaseC dt, RMap (CaseClauses dt), clauses ~ Rec (f ret) (CaseClauses dt), ScopeCodeGen ret) instance (name GHC.Types.~ GHC.TypeLits.AppendSymbol "c" ctor, Lorentz.Constraints.Scopes.KnownValue x) => Lorentz.ADT.CaseArrow name (Indigo.Backend.Case.IndigoClause x ret) (Indigo.Backend.Case.IndigoCaseClauseL ret ('Michelson.Typed.Haskell.Instr.Sum.CaseClauseParam ctor ('Michelson.Typed.Haskell.Instr.Sum.OneField x))) -- | Strictly typed statements of Indigo language. module Indigo.Backend -- | For statements to iterate over a container. forEach :: (IterOpHs a, KnownValue (IterOpElHs a)) => Expr a -> Var (IterOpElHs a) -> SomeIndigoState (IterOpElHs a : inp) -> IndigoState inp inp -- | While statement. while :: Expr Bool -> SomeIndigoState inp -> IndigoState inp inp -- | While-left statement. Repeats a block of code as long as the control -- Either is Left, returns when it is Right. whileLeft :: forall l r inp. (KnownValue l, KnownValue r) => Expr (Either l r) -> Var l -> SomeIndigoState (l : inp) -> Var r -> IndigoState inp (r : inp) selfCalling :: forall p inp mname. (NiceParameterFull p, KnownValue (GetEntrypointArgCustom p mname)) => EntrypointRef mname -> Var (ContractRef (GetEntrypointArgCustom p mname)) -> IndigoState inp (ContractRef (GetEntrypointArgCustom p mname) : inp) contractCalling :: forall cp inp epRef epArg addr. (HasEntrypointArg cp epRef epArg, ToTAddress cp addr, ToT addr ~ ToT Address, KnownValue epArg) => epRef -> Expr addr -> Var (Maybe (ContractRef epArg)) -> IndigoState inp (Maybe (ContractRef epArg) : inp) -- | Put a document item. doc :: DocItem di => di -> IndigoState s s -- | Group documentation built in the given piece of code into a block -- dedicated to one thing, e.g. to one entrypoint. docGroup :: DocGrouping -> SomeIndigoState i -> SomeIndigoState i -- | Insert documentation of the contract storage type. The type should be -- passed using type applications. docStorage :: forall storage s. TypeHasDoc storage => IndigoState s s -- | Give a name to the given contract. Apply it to the whole contract -- code. contractName :: Text -> SomeIndigoState i -> SomeIndigoState i -- | Indigo version for the function of the same name from Lorentz. finalizeParamCallingDoc :: (NiceParameterFull cp, RequireSumType cp, HasCallStack) => Var cp -> SomeIndigoState (cp : inp) -> Expr cp -> SomeIndigoState inp -- | Attach general info to the given contract. contractGeneral :: SomeIndigoState i -> SomeIndigoState i -- | Attach default general info to the contract documentation. contractGeneralDefault :: IndigoState s s transferTokens :: (NiceParameter p, HasSideEffects) => Expr p -> Expr Mutez -> Expr (ContractRef p) -> IndigoState inp inp setDelegate :: HasSideEffects => Expr (Maybe KeyHash) -> IndigoState inp inp createContract :: (HasSideEffects, NiceStorage s, NiceParameterFull p) => Contract p s -> Expr (Maybe KeyHash) -> Expr Mutez -> Expr s -> Var Address -> IndigoState inp (Address : inp) -- | Takes an arbitrary IndigoM and wraps it into an -- IndigoFunction producing a local scope for its execution. -- Once it executed, all non-returned variables are cleaned up so that -- the stack has only returned variables at the top. This also can be -- interpreted as if True then f else nop. -- -- Note, that by default we do not define scope inside indigo functions, -- meaning that once we want to create a new variable or return it from a -- function we need to do it inside scope $ instr construction, -- for example: -- --
-- f :: IndigoFunction s Natural -- f = scope $ do -- *[s]* -- res <- newVar (0 :: Natural) -- *[Natural, s]* -- scope $ do -- _n <- newVar (1 :: Integer) -- *[Integer, Natural, s] -- res += 4 -- *[Natural, s]* -- return res -- *[s]* --scope :: forall ret inp. ScopeCodeGen ret => SomeIndigoState inp -> ret -> RetVars ret -> IndigoState inp (RetOutStack ret ++ inp) -- | Add a comment comment :: CommentType -> IndigoState i i -- | StatementF functor datatype for Freer monad module Indigo.Frontend.Statement -- | StatementF functor for Freer monad. -- -- The constructors correspond to every Indigo statement that has -- expressions (Expr x) in its signature. -- -- The ones that don't take expressions are compiled directly to -- IndigoState (and kept in LiftIndigoState), because they -- won't be taken into consideration by an optimizer anyway. -- -- One more detail about StatementF is that it takes a -- cont type parameter, which is basically IndigoM -- (freer monad), to avoid cyclic dependencies. cont is needed -- to support statements which have recursive structure (like: -- if, while, case, etc). data StatementF (freer :: Type -> Type) a -- | Direct injection of IndigoState of statements which are not going to -- be analyzed by optimizer. [LiftIndigoState] :: (forall inp. SomeIndigoState inp) -> StatementF freer () -- | Constructor wrapper which holds IndigoM function among with -- the callstack of caller side. -- -- The another option could be to add HasCallStack to -- Instr constructor of Program but this would have -- held only a CallStack of separate primitive statement (unlike -- updateStorageField, etc). The idea is to be able to have -- correspondence between original Indigo code and the generated -- Michelson assembler and vice versa to perform quick navigation and -- analyze, so it's better to have call stack for non-primitive frontend -- statements. [CalledFrom] :: CallStack -> freer a -> StatementF freer a [NewVar] :: KnownValue x => Expr x -> StatementF freer (Var x) [SetVar] :: KnownValue x => Var x -> Expr x -> StatementF freer () [VarModification] :: (IsObject x, KnownValue y) => ([y, x] :-> '[x]) -> Var x -> Expr y -> StatementF freer () [SetField] :: (IsObject dt, IsObject ftype, HasField dt fname ftype) => Var dt -> Label fname -> Expr ftype -> StatementF cont () [LambdaCall1] :: LambdaKind st arg res extra -> String -> (Var arg -> freer res) -> Expr arg -> StatementF freer (RetVars res) [Scope] :: ScopeCodeGen a => freer a -> StatementF freer (RetVars a) [If] :: IfConstraint a b => Expr Bool -> freer a -> freer b -> StatementF freer (RetVars a) [IfSome] :: (IfConstraint a b, KnownValue x) => Expr (Maybe x) -> (Var x -> freer a) -> freer b -> StatementF freer (RetVars a) [IfRight] :: (IfConstraint a b, KnownValue x, KnownValue y) => Expr (Either y x) -> (Var x -> freer a) -> (Var y -> freer b) -> StatementF freer (RetVars a) [IfCons] :: (IfConstraint a b, KnownValue x) => Expr (List x) -> (Var x -> Var (List x) -> freer a) -> freer b -> StatementF freer (RetVars a) [Case] :: CaseCommonF (IndigoMCaseClauseL freer) dt ret clauses => Expr dt -> clauses -> StatementF freer (RetVars ret) [EntryCase] :: (CaseCommonF (IndigoMCaseClauseL freer) dt ret clauses, DocumentEntrypoints entrypointKind dt) => Proxy entrypointKind -> Expr dt -> clauses -> StatementF freer (RetVars ret) [EntryCaseSimple] :: (CaseCommonF (IndigoMCaseClauseL freer) cp ret clauses, DocumentEntrypoints PlainEntrypointsKind cp, NiceParameterFull cp, RequireFlatParamEps cp) => Expr cp -> clauses -> StatementF freer (RetVars ret) [While] :: Expr Bool -> freer () -> StatementF freer () [WhileLeft] :: (KnownValue x, KnownValue y) => Expr (Either y x) -> (Var y -> freer ()) -> StatementF freer (Var x) [ForEach] :: (IterOpHs a, KnownValue (IterOpElHs a)) => Expr a -> (Var (IterOpElHs a) -> freer ()) -> StatementF freer () [ContractName] :: Text -> freer () -> StatementF freer () [DocGroup] :: DocGrouping -> freer () -> StatementF freer () [ContractGeneral] :: freer () -> StatementF freer () [FinalizeParamCallingDoc] :: (NiceParameterFull cp, RequireSumType cp, HasCallStack) => (Var cp -> freer ()) -> Expr cp -> StatementF freer () [TransferTokens] :: (NiceParameter p, HasSideEffects) => Expr p -> Expr Mutez -> Expr (ContractRef p) -> StatementF freer () [SetDelegate] :: HasSideEffects => Expr (Maybe KeyHash) -> StatementF freer () [CreateContract] :: (IsObject st, NiceStorage st, NiceParameterFull param, HasSideEffects) => Contract param st -> Expr (Maybe KeyHash) -> Expr Mutez -> Expr st -> StatementF freer (Var Address) [SelfCalling] :: (NiceParameterFull p, KnownValue (GetEntrypointArgCustom p mname)) => Proxy p -> EntrypointRef mname -> StatementF freer (Var (ContractRef (GetEntrypointArgCustom p mname))) [ContractCalling] :: (HasEntrypointArg cp epRef epArg, ToTAddress cp addr, ToT addr ~ ToT Address, KnownValue epArg) => Proxy cp -> epRef -> Expr addr -> StatementF freer (Var (Maybe (ContractRef epArg))) [Fail] :: ReturnableValue ret => Proxy ret -> (forall inp. SomeIndigoState inp) -> StatementF freer (RetVars ret) [FailOver] :: ReturnableValue ret => Proxy ret -> (forall inp. Expr a -> SomeIndigoState inp) -> Expr a -> StatementF freer (RetVars ret) type IfConstraint a b = (ScopeCodeGen a, ScopeCodeGen b, CompareBranchesResults (RetExprs a) (RetExprs b), RetVars a ~ RetVars b, RetOutStack a ~ RetOutStack b) -- | Analogous datatype as IndigoCaseClauseL from Indigo.Backend.Case data IndigoMCaseClauseL freer ret (param :: CaseClauseParam) [OneFieldIndigoMCaseClauseL] :: (name ~ AppendSymbol "c" ctor, KnownValue x, ScopeCodeGen retBr, ret ~ RetExprs retBr, RetOutStack ret ~ RetOutStack retBr) => Label name -> (Var x -> freer retBr) -> IndigoMCaseClauseL freer ret ('CaseClauseParam ctor ('OneField x)) -- | Describes kind of lambda: pure, modifying storage, effectfull data LambdaKind st arg res extra [PureLambda] :: (ExecuteLambdaPure1C arg res, CreateLambda1CGeneric '[] arg res, Typeable res) => LambdaKind st arg res '[] [StorageLambda] :: (ExecuteLambda1C st arg res, CreateLambda1CGeneric '[st] arg res, Typeable res) => Proxy st -> LambdaKind st arg res '[st] [EffLambda] :: (ExecuteLambdaEff1C st arg res, CreateLambda1CGeneric '[st, Ops] arg res, Typeable res) => Proxy st -> LambdaKind st arg res '[st, Ops] -- | Provide common constraints that are presented in all constructors of -- LambdaKind withLambdaKind :: LambdaKind st arg res extra -> ((ScopeCodeGen res, KnownValue arg, Typeable res, CreateLambda1CGeneric extra arg res) => r) -> r module Indigo.Frontend.Program -- | Monad for writing your contracts in. newtype IndigoM a IndigoM :: Program (StatementF IndigoM) a -> IndigoM a [unIndigoM] :: IndigoM a -> Program (StatementF IndigoM) a -- | This is freer monad (in other words operational monad). -- -- It preserves the structure of the computation performed over it, -- including return and bind operations. This was -- introduced to be able to iterate over Indigo code and optimize/analyze -- it. -- -- You can read a clearer description of this construction in "The Book -- of Monads" by Alejandro Serrano. There is a chapter about free monads, -- specifically about Freer you can read at page 259. There is -- "operational" package which contains transformer of this monad and -- auxiliary functions but it's not used because we are using only some -- basics of it. data Program instr a [Done] :: a -> Program instr a [Instr] :: instr a -> Program instr a [Bind] :: Program instr a -> (a -> Program instr b) -> Program instr b -- | Traverse over Freer structure and interpret it interpretProgram :: Monad m => (forall x. instr x -> m x) -> Program instr a -> m a -- | Type of a contract that can be compiled to Lorentz with -- compileIndigoContract. type IndigoContract param st = (HasStorage st, HasSideEffects) => Var param -> IndigoM () instance GHC.Base.Monad Indigo.Frontend.Program.IndigoM instance GHC.Base.Applicative Indigo.Frontend.Program.IndigoM instance GHC.Base.Functor Indigo.Frontend.Program.IndigoM instance GHC.Base.Functor (Indigo.Frontend.Program.Program instr) instance GHC.Base.Applicative (Indigo.Frontend.Program.Program instr) instance GHC.Base.Monad (Indigo.Frontend.Program.Program instr) -- | Instruction datatype and its compilations. -- -- The idea behind this module is to provide an intermediate -- representation that can: -- --
-- {-# LANGUAGE NoApplicativeDo, RebindableSyntax #-}
-- {-# OPTIONS_GHC -Wno-unused-do-bind #-}
--
module Indigo.Rebinded
-- | Defines semantics of if ... then ... else ... construction
-- for Indigo where the predicate is a generic exa for which
-- IsExpr exa Bool holds
ifThenElse :: (IfConstraint a b, IsExpr exa Bool) => exa -> IndigoM a -> IndigoM b -> IndigoM (RetVars a)
-- | Defines numerical literals resolution for Indigo.
--
-- It is implemented with an additional NumType argument that
-- disambiguates the resulting type. This allows, for example, 1
-- int to be resolved to 1 :: Integer.
fromInteger :: Integer -> NumType n t -> t
-- | Numerical literal disambiguation value for a Natural, see
-- fromInteger.
nat :: NumType 'Nat Natural
-- | Numerical literal disambiguation value for an Integer, see
-- fromInteger.
int :: NumType 'Int Integer
-- | Numerical literal disambiguation value for a Mutez, see
-- fromInteger.
mutez :: NumType 'Mtz Mutez
class IsLabel (x :: Symbol) a
fromLabel :: IsLabel x a => a
-- | Standard library for Indigo.
--
-- As opposed to Expr and Language modules, this module contains quite
-- standard things that are not present in vanilla Michelson and are not
-- typically found in imperative high level languages.
module Indigo.Lib
-- | Indigo version of the view macro. It takes a function from
-- view argument to view result and a View structure that
-- typically comes from a top-level case.
view_ :: forall arg r viewExpr exr. (KnownValue arg, NiceParameter r, viewExpr :~> View arg r, exr :~> r, HasSideEffects) => (Expr arg -> IndigoM exr) -> viewExpr -> IndigoM ()
-- | Indigo version of the void macro.
void_ :: forall a b voidExpr exb. (KnownValue a, IsError (VoidResult b), NiceConstant b, voidExpr :~> Void_ a b, exb :~> b) => (Expr a -> IndigoM exb) -> voidExpr -> IndigoM ()
-- | Flipped version of view_ that is present due to the common
-- appearance of flip view parameter $ instr construction.
--
-- Semantically we "project" the given parameter inside the body of the
-- View construction.
project :: forall arg r viewExpr exr. (KnownValue arg, NiceParameter r, viewExpr :~> View arg r, exr :~> r, HasSideEffects) => viewExpr -> (Expr arg -> IndigoM exr) -> IndigoM ()
-- | Flipped version of void_ that is present due to the common
-- appearance of flip void_ parameter $ instr construction.
projectVoid :: forall a b voidExpr exb. (KnownValue a, IsError (VoidResult b), NiceConstant b, voidExpr :~> Void_ a b, exb :~> b) => voidExpr -> (Expr a -> IndigoM exb) -> IndigoM ()
-- | If the first value is greater than the second one, it returns their
-- difference. If the values are equal, it returns Nothing.
-- Otherwise it fails using the supplied function.
subGt0 :: (ex1 :~> Natural, ex2 :~> Natural) => ex1 -> ex2 -> IndigoM () -> IndigoFunction (Maybe Natural)
module Indigo
-- | Append two lists, i.e.,
--
-- -- [x1, ..., xm] ++ [y1, ..., yn] == [x1, ..., xm, y1, ..., yn] -- [x1, ..., xm] ++ [y1, ...] == [x1, ..., xm, y1, ...] ---- -- If the first list is not finite, the result is the first list. (++) :: [a] -> [a] -> [a] infixr 5 ++ -- | The value of seq a b is bottom if a is bottom, and -- otherwise equal to b. In other words, it evaluates the first -- argument a to weak head normal form (WHNF). seq is -- usually introduced to improve performance by avoiding unneeded -- laziness. -- -- A note on evaluation order: the expression seq a b does -- not guarantee that a will be evaluated before -- b. The only guarantee given by seq is that the both -- a and b will be evaluated before seq -- returns a value. In particular, this means that b may be -- evaluated before a. If you need to guarantee a specific order -- of evaluation, you must use the function pseq from the -- "parallel" package. seq :: a -> b -> b infixr 0 `seq` -- | O(n). filter, applied to a predicate and a list, returns -- the list of those elements that satisfy the predicate; i.e., -- --
-- filter p xs = [ x | x <- xs, p x] ---- --
-- >>> filter odd [1, 2, 3] -- [1,3] --filter :: (a -> Bool) -> [a] -> [a] -- | O(min(m,n)). zip takes two lists and returns a list of -- corresponding pairs. -- --
-- zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')] ---- -- If one input list is short, excess elements of the longer list are -- discarded: -- --
-- zip [1] ['a', 'b'] = [(1, 'a')] -- zip [1, 2] ['a'] = [(1, 'a')] ---- -- zip is right-lazy: -- --
-- zip [] _|_ = [] -- zip _|_ [] = _|_ ---- -- zip is capable of list fusion, but it is restricted to its -- first list argument and its resulting list. zip :: [a] -> [b] -> [(a, b)] -- | otherwise is defined as the value True. It helps to make -- guards more readable. eg. -- --
-- f x | x < 0 = ... -- | otherwise = ... --otherwise :: Bool -- | Application operator. This operator is redundant, since ordinary -- application (f x) means the same as (f $ x). -- However, $ has low, right-associative binding precedence, so it -- sometimes allows parentheses to be omitted; for example: -- --
-- f $ g $ h x = f (g (h x)) ---- -- It is also useful in higher-order situations, such as map -- ($ 0) xs, or zipWith ($) fs xs. -- -- Note that ($) is levity-polymorphic in its result -- type, so that foo $ True where foo :: Bool -> -- Int# is well-typed. ($) :: forall (r :: RuntimeRep) a (b :: TYPE r). (a -> b) -> a -> b infixr 0 $ -- | general coercion from integral types fromIntegral :: (Integral a, Num b) => a -> b -- | general coercion to fractional types realToFrac :: (Real a, Fractional b) => a -> b -- | Conditional failure of Alternative computations. Defined by -- --
-- guard True = pure () -- guard False = empty ---- --
-- >>> safeDiv 4 0 -- Nothing -- >>> safeDiv 4 2 -- Just 2 ---- -- A definition of safeDiv using guards, but not guard: -- --
-- safeDiv :: Int -> Int -> Maybe Int -- safeDiv x y | y /= 0 = Just (x `div` y) -- | otherwise = Nothing ---- -- A definition of safeDiv using guard and Monad -- do-notation: -- --
-- safeDiv :: Int -> Int -> Maybe Int -- safeDiv x y = do -- guard (y /= 0) -- return (x `div` y) --guard :: Alternative f => Bool -> f () -- | The join function is the conventional monad join operator. It -- is used to remove one level of monadic structure, projecting its bound -- argument into the outer level. -- --
-- atomically :: STM a -> IO a ---- -- is used to run STM transactions atomically. So, by specializing -- the types of atomically and join to -- --
-- atomically :: STM (IO b) -> IO (IO b) -- join :: IO (IO b) -> IO b ---- -- we can compose them as -- --
-- join . atomically :: STM (IO b) -> IO b ---- -- to run an STM transaction and the IO action it returns. join :: Monad m => m (m a) -> m a -- | The Bounded class is used to name the upper and lower limits of -- a type. Ord is not a superclass of Bounded since types -- that are not totally ordered may also have upper and lower bounds. -- -- The Bounded class may be derived for any enumeration type; -- minBound is the first constructor listed in the data -- declaration and maxBound is the last. Bounded may also -- be derived for single-constructor datatypes whose constituent types -- are in Bounded. class Bounded a minBound :: Bounded a => a maxBound :: Bounded a => a -- | Class Enum defines operations on sequentially ordered types. -- -- The enumFrom... methods are used in Haskell's translation of -- arithmetic sequences. -- -- Instances of Enum may be derived for any enumeration type -- (types whose constructors have no fields). The nullary constructors -- are assumed to be numbered left-to-right by fromEnum from -- 0 through n-1. See Chapter 10 of the Haskell -- Report for more details. -- -- For any type that is an instance of class Bounded as well as -- Enum, the following should hold: -- --
-- enumFrom x = enumFromTo x maxBound -- enumFromThen x y = enumFromThenTo x y bound -- where -- bound | fromEnum y >= fromEnum x = maxBound -- | otherwise = minBound --class Enum a -- | the successor of a value. For numeric types, succ adds 1. succ :: Enum a => a -> a -- | the predecessor of a value. For numeric types, pred subtracts -- 1. pred :: Enum a => a -> a -- | Convert from an Int. toEnum :: Enum a => Int -> a -- | Convert to an Int. It is implementation-dependent what -- fromEnum returns when applied to a value that is too large to -- fit in an Int. fromEnum :: Enum a => a -> Int -- | Used in Haskell's translation of [n..] with [n..] = -- enumFrom n, a possible implementation being enumFrom n = n : -- enumFrom (succ n). For example: -- --
enumFrom 4 :: [Integer] = [4,5,6,7,...]
enumFrom 6 :: [Int] = [6,7,8,9,...,maxBound :: -- Int]
enumFromThen 4 6 :: [Integer] = [4,6,8,10...]
enumFromThen 6 2 :: [Int] = [6,2,-2,-6,...,minBound :: -- Int]
enumFromTo 6 10 :: [Int] = [6,7,8,9,10]
enumFromTo 42 1 :: [Integer] = []
enumFromThenTo 4 2 -6 :: [Integer] = -- [4,2,0,-2,-4,-6]
enumFromThenTo 6 8 2 :: [Int] = []
-- (x `quot` y)*y + (x `rem` y) == x --rem :: Integral a => a -> a -> a -- | simultaneous quot and rem quotRem :: Integral a => a -> a -> (a, a) -- | simultaneous div and mod divMod :: Integral a => a -> a -> (a, a) -- | conversion to Integer toInteger :: Integral a => a -> Integer infixl 7 `quot` infixl 7 `rem` -- | The Monad class defines the basic operations over a -- monad, a concept from a branch of mathematics known as -- category theory. From the perspective of a Haskell programmer, -- however, it is best to think of a monad as an abstract datatype -- of actions. Haskell's do expressions provide a convenient -- syntax for writing monadic expressions. -- -- Instances of Monad should satisfy the following: -- --
-- abs x * signum x == x ---- -- For real numbers, the signum is either -1 (negative), -- 0 (zero) or 1 (positive). signum :: Num a => a -> a -- | The Ord class is used for totally ordered datatypes. -- -- Instances of Ord can be derived for any user-defined datatype -- whose constituent types are in Ord. The declared order of the -- constructors in the data declaration determines the ordering in -- derived Ord instances. The Ordering datatype allows a -- single comparison to determine the precise ordering of two objects. -- -- The Haskell Report defines no laws for Ord. However, -- <= is customarily expected to implement a non-strict partial -- order and have the following properties: -- --
-- infixr 5 :^: -- data Tree a = Leaf a | Tree a :^: Tree a ---- -- the derived instance of Read in Haskell 2010 is equivalent to -- --
-- instance (Read a) => Read (Tree a) where
--
-- readsPrec d r = readParen (d > app_prec)
-- (\r -> [(Leaf m,t) |
-- ("Leaf",s) <- lex r,
-- (m,t) <- readsPrec (app_prec+1) s]) r
--
-- ++ readParen (d > up_prec)
-- (\r -> [(u:^:v,w) |
-- (u,s) <- readsPrec (up_prec+1) r,
-- (":^:",t) <- lex s,
-- (v,w) <- readsPrec (up_prec+1) t]) r
--
-- where app_prec = 10
-- up_prec = 5
--
--
-- Note that right-associativity of :^: is unused.
--
-- The derived instance in GHC is equivalent to
--
-- -- instance (Read a) => Read (Tree a) where -- -- readPrec = parens $ (prec app_prec $ do -- Ident "Leaf" <- lexP -- m <- step readPrec -- return (Leaf m)) -- -- +++ (prec up_prec $ do -- u <- step readPrec -- Symbol ":^:" <- lexP -- v <- step readPrec -- return (u :^: v)) -- -- where app_prec = 10 -- up_prec = 5 -- -- readListPrec = readListPrecDefault ---- -- Why do both readsPrec and readPrec exist, and why does -- GHC opt to implement readPrec in derived Read instances -- instead of readsPrec? The reason is that readsPrec is -- based on the ReadS type, and although ReadS is mentioned -- in the Haskell 2010 Report, it is not a very efficient parser data -- structure. -- -- readPrec, on the other hand, is based on a much more efficient -- ReadPrec datatype (a.k.a "new-style parsers"), but its -- definition relies on the use of the RankNTypes language -- extension. Therefore, readPrec (and its cousin, -- readListPrec) are marked as GHC-only. Nevertheless, it is -- recommended to use readPrec instead of readsPrec -- whenever possible for the efficiency improvements it brings. -- -- As mentioned above, derived Read instances in GHC will -- implement readPrec instead of readsPrec. The default -- implementations of readsPrec (and its cousin, readList) -- will simply use readPrec under the hood. If you are writing a -- Read instance by hand, it is recommended to write it like so: -- --
-- instance Read T where -- readPrec = ... -- readListPrec = readListPrecDefault --class Read a class (Num a, Ord a) => Real a -- | the rational equivalent of its real argument with full precision toRational :: Real a => a -> Rational -- | Extracting components of fractions. class (Real a, Fractional a) => RealFrac a -- | The function properFraction takes a real fractional number -- x and returns a pair (n,f) such that x = -- n+f, and: -- --
-- infixr 5 :^: -- data Tree a = Leaf a | Tree a :^: Tree a ---- -- the derived instance of Show is equivalent to -- --
-- instance (Show a) => Show (Tree a) where -- -- showsPrec d (Leaf m) = showParen (d > app_prec) $ -- showString "Leaf " . showsPrec (app_prec+1) m -- where app_prec = 10 -- -- showsPrec d (u :^: v) = showParen (d > up_prec) $ -- showsPrec (up_prec+1) u . -- showString " :^: " . -- showsPrec (up_prec+1) v -- where up_prec = 5 ---- -- Note that right-associativity of :^: is ignored. For example, -- --
-- fail s >>= f = fail s ---- -- If your Monad is also MonadPlus, a popular definition is -- --
-- fail _ = mzero --class Monad m => MonadFail (m :: Type -> Type) fail :: MonadFail m => String -> m a -- | Class for string-like datastructures; used by the overloaded string -- extension (-XOverloadedStrings in GHC). class IsString a fromString :: IsString a => String -> a -- | A functor with application, providing operations to -- --
-- (<*>) = liftA2 id ---- --
-- liftA2 f x y = f <$> x <*> y ---- -- Further, any definition must satisfy the following: -- --
pure id <*> v = -- v
pure (.) <*> u -- <*> v <*> w = u <*> (v -- <*> w)
pure f <*> -- pure x = pure (f x)
u <*> pure y = -- pure ($ y) <*> u
-- forall x y. p (q x y) = f x . g y ---- -- it follows from the above that -- --
-- liftA2 p (liftA2 q u v) = liftA2 f u . liftA2 g v ---- -- If f is also a Monad, it should satisfy -- -- -- -- (which implies that pure and <*> satisfy the -- applicative functor laws). class Functor f => Applicative (f :: Type -> Type) -- | Lift a value. pure :: Applicative f => a -> f a -- | Sequential application. -- -- A few functors support an implementation of <*> that is -- more efficient than the default one. (<*>) :: Applicative f => f (a -> b) -> f a -> f b -- | Lift a binary function to actions. -- -- Some functors support an implementation of liftA2 that is more -- efficient than the default one. In particular, if fmap is an -- expensive operation, it is likely better to use liftA2 than to -- fmap over the structure and then use <*>. liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c -- | Sequence actions, discarding the value of the first argument. (*>) :: Applicative f => f a -> f b -> f b -- | Sequence actions, discarding the value of the second argument. (<*) :: Applicative f => f a -> f b -> f a infixl 4 <*> infixl 4 *> infixl 4 <* -- | Data structures that can be folded. -- -- For example, given a data type -- --
-- data Tree a = Empty | Leaf a | Node (Tree a) a (Tree a) ---- -- a suitable instance would be -- --
-- instance Foldable Tree where -- foldMap f Empty = mempty -- foldMap f (Leaf x) = f x -- foldMap f (Node l k r) = foldMap f l `mappend` f k `mappend` foldMap f r ---- -- This is suitable even for abstract types, as the monoid is assumed to -- satisfy the monoid laws. Alternatively, one could define -- foldr: -- --
-- instance Foldable Tree where -- foldr f z Empty = z -- foldr f z (Leaf x) = f x z -- foldr f z (Node l k r) = foldr f (f k (foldr f z r)) l ---- -- Foldable instances are expected to satisfy the following -- laws: -- --
-- foldr f z t = appEndo (foldMap (Endo . f) t ) z ---- --
-- foldl f z t = appEndo (getDual (foldMap (Dual . Endo . flip f) t)) z ---- --
-- fold = foldMap id ---- --
-- length = getSum . foldMap (Sum . const 1) ---- -- sum, product, maximum, and minimum -- should all be essentially equivalent to foldMap forms, such -- as -- --
-- sum = getSum . foldMap Sum ---- -- but may be less defined. -- -- If the type is also a Functor instance, it should satisfy -- --
-- foldMap f = fold . fmap f ---- -- which implies that -- --
-- foldMap f . fmap g = foldMap (f . g) --class Foldable (t :: Type -> Type) -- | Functors representing data structures that can be traversed from left -- to right. -- -- A definition of traverse must satisfy the following laws: -- --
-- t :: (Applicative f, Applicative g) => f a -> g a ---- -- preserving the Applicative operations, i.e. -- --
-- t (pure x) = pure x -- t (f <*> x) = t f <*> t x ---- -- and the identity functor Identity and composition functors -- Compose are from Data.Functor.Identity and -- Data.Functor.Compose. -- -- (The naturality law is implied by parametricity.) -- -- Instances are similar to Functor, e.g. given a data type -- --
-- data Tree a = Empty | Leaf a | Node (Tree a) a (Tree a) ---- -- a suitable instance would be -- --
-- instance Traversable Tree where -- traverse f Empty = pure Empty -- traverse f (Leaf x) = Leaf <$> f x -- traverse f (Node l k r) = Node <$> traverse f l <*> f k <*> traverse f r ---- -- This is suitable even for abstract types, as the laws for -- <*> imply a form of associativity. -- -- The superclass instances should satisfy the following: -- --
-- from . to ≡ id -- to . from ≡ id --class Generic a -- | This class gives the integer associated with a type-level natural. -- There are instances of the class for every concrete literal: 0, 1, 2, -- etc. class KnownNat (n :: Nat) class IsLabel (x :: Symbol) a fromLabel :: IsLabel x a => a -- | The class of semigroups (types with an associative binary operation). -- -- Instances should satisfy the following: -- -- class Semigroup a -- | Reduce a non-empty list with <> -- -- The default definition should be sufficient, but this can be -- overridden for efficiency. sconcat :: Semigroup a => NonEmpty a -> a -- | Repeat a value n times. -- -- Given that this works on a Semigroup it is allowed to fail if -- you request 0 or fewer repetitions, and the default definition will do -- so. -- -- By making this a member of the class, idempotent semigroups and -- monoids can upgrade this to execute in O(1) by picking -- stimes = stimesIdempotent or stimes = -- stimesIdempotentMonoid respectively. stimes :: (Semigroup a, Integral b) => b -> a -> a -- | The class of monoids (types with an associative binary operation that -- has an identity). Instances should satisfy the following: -- --
-- >>> 2^100 :: Natural -- 1267650600228229401496703205376 ---- -- Operations whose result would be negative throw -- (Underflow :: ArithException), -- --
-- >>> -1 :: Natural -- *** Exception: arithmetic underflow --data Natural -- | The Maybe type encapsulates an optional value. A value of type -- Maybe a either contains a value of type a -- (represented as Just a), or it is empty (represented -- as Nothing). Using Maybe is a good way to deal with -- errors or exceptional cases without resorting to drastic measures such -- as error. -- -- The Maybe type is also a monad. It is a simple kind of error -- monad, where all errors are represented by Nothing. A richer -- error monad can be built using the Either type. data Maybe a Nothing :: Maybe a Just :: a -> Maybe a data Ordering LT :: Ordering EQ :: Ordering GT :: Ordering -- | Rational numbers, with numerator and denominator of some -- Integral type. -- -- Note that Ratio's instances inherit the deficiencies from the -- type parameter's. For example, Ratio Natural's Num -- instance has similar problems to Natural's. data Ratio a (:%) :: !a -> !a -> Ratio a -- | Arbitrary-precision rational numbers, represented as a ratio of two -- Integer values. A rational number may be constructed using the -- % operator. type Rational = Ratio Integer -- | A value of type IO a is a computation which, when -- performed, does some I/O before returning a value of type a. -- -- There is really only one way to "perform" an I/O action: bind it to -- Main.main in your program. When your program is run, the I/O -- will be performed. It isn't possible to perform I/O from an arbitrary -- function, unless that function is itself in the IO monad and -- called at some point, directly or indirectly, from Main.main. -- -- IO is a monad, so IO actions can be combined using -- either the do-notation or the >> and >>= -- operations from the Monad class. data IO a -- | A Word is an unsigned integral type, with the same size as -- Int. data Word -- | 8-bit unsigned integer type data Word8 -- | 16-bit unsigned integer type data Word16 -- | 32-bit unsigned integer type data Word32 -- | 64-bit unsigned integer type data Word64 -- | A value of type Ptr a represents a pointer to an -- object, or an array of objects, which may be marshalled to or from -- Haskell values of type a. -- -- The type a will often be an instance of class Storable -- which provides the marshalling operations. However this is not -- essential, and you can provide your own operations to access the -- pointer. For example you might write small foreign functions to get or -- set the fields of a C struct. data Ptr a -- | A value of type FunPtr a is a pointer to a function -- callable from foreign code. The type a will normally be a -- foreign type, a function type with zero or more arguments where -- --
-- foreign import ccall "stdlib.h &free" -- p_free :: FunPtr (Ptr a -> IO ()) ---- -- or a pointer to a Haskell function created using a wrapper stub -- declared to produce a FunPtr of the correct type. For example: -- --
-- type Compare = Int -> Int -> Bool -- foreign import ccall "wrapper" -- mkCompare :: Compare -> IO (FunPtr Compare) ---- -- Calls to wrapper stubs like mkCompare allocate storage, which -- should be released with freeHaskellFunPtr when no longer -- required. -- -- To convert FunPtr values to corresponding Haskell functions, -- one can define a dynamic stub for the specific foreign type, -- e.g. -- --
-- type IntFunction = CInt -> IO () -- foreign import ccall "dynamic" -- mkFun :: FunPtr IntFunction -> IntFunction --data FunPtr a -- | The Either type represents values with two possibilities: a -- value of type Either a b is either Left -- a or Right b. -- -- The Either type is sometimes used to represent a value which is -- either correct or an error; by convention, the Left constructor -- is used to hold an error value and the Right constructor is -- used to hold a correct value (mnemonic: "right" also means "correct"). -- --
-- >>> let s = Left "foo" :: Either String Int -- -- >>> s -- Left "foo" -- -- >>> let n = Right 3 :: Either String Int -- -- >>> n -- Right 3 -- -- >>> :type s -- s :: Either String Int -- -- >>> :type n -- n :: Either String Int ---- -- The fmap from our Functor instance will ignore -- Left values, but will apply the supplied function to values -- contained in a Right: -- --
-- >>> let s = Left "foo" :: Either String Int -- -- >>> let n = Right 3 :: Either String Int -- -- >>> fmap (*2) s -- Left "foo" -- -- >>> fmap (*2) n -- Right 6 ---- -- The Monad instance for Either allows us to chain -- together multiple actions which may fail, and fail overall if any of -- the individual steps failed. First we'll write a function that can -- either parse an Int from a Char, or fail. -- --
-- >>> import Data.Char ( digitToInt, isDigit )
--
-- >>> :{
-- let parseEither :: Char -> Either String Int
-- parseEither c
-- | isDigit c = Right (digitToInt c)
-- | otherwise = Left "parse error"
--
-- >>> :}
--
--
-- The following should work, since both '1' and '2'
-- can be parsed as Ints.
--
--
-- >>> :{
-- let parseMultiple :: Either String Int
-- parseMultiple = do
-- x <- parseEither '1'
-- y <- parseEither '2'
-- return (x + y)
--
-- >>> :}
--
--
-- -- >>> parseMultiple -- Right 3 ---- -- But the following should fail overall, since the first operation where -- we attempt to parse 'm' as an Int will fail: -- --
-- >>> :{
-- let parseMultiple :: Either String Int
-- parseMultiple = do
-- x <- parseEither 'm'
-- y <- parseEither '2'
-- return (x + y)
--
-- >>> :}
--
--
-- -- >>> parseMultiple -- Left "parse error" --data Either a b Left :: a -> Either a b Right :: b -> Either a b -- | The kind of constraints, like Show a data Constraint -- | Comparison of type-level naturals, as a function. type family CmpNat (a :: Nat) (b :: Nat) :: Ordering -- | Coercible is a two-parameter class that has instances for -- types a and b if the compiler can infer that they -- have the same representation. This class does not have regular -- instances; instead they are created on-the-fly during type-checking. -- Trying to manually declare an instance of Coercible is an -- error. -- -- Nevertheless one can pretend that the following three kinds of -- instances exist. First, as a trivial base-case: -- --
-- instance Coercible a a ---- -- Furthermore, for every type constructor there is an instance that -- allows to coerce under the type constructor. For example, let -- D be a prototypical type constructor (data or -- newtype) with three type arguments, which have roles -- nominal, representational resp. phantom. -- Then there is an instance of the form -- --
-- instance Coercible b b' => Coercible (D a b c) (D a b' c') ---- -- Note that the nominal type arguments are equal, the -- representational type arguments can differ, but need to have -- a Coercible instance themself, and the phantom type -- arguments can be changed arbitrarily. -- -- The third kind of instance exists for every newtype NT = MkNT -- T and comes in two variants, namely -- --
-- instance Coercible a T => Coercible a NT ---- --
-- instance Coercible T b => Coercible NT b ---- -- This instance is only usable if the constructor MkNT is in -- scope. -- -- If, as a library author of a type constructor like Set a, you -- want to prevent a user of your module to write coerce :: Set T -- -> Set NT, you need to set the role of Set's type -- parameter to nominal, by writing -- --
-- type role Set nominal ---- -- For more details about this feature, please refer to Safe -- Coercions by Joachim Breitner, Richard A. Eisenberg, Simon Peyton -- Jones and Stephanie Weirich. class a ~R# b => Coercible (a :: k) (b :: k) -- | CallStacks are a lightweight method of obtaining a partial -- call-stack at any point in the program. -- -- A function can request its call-site with the HasCallStack -- constraint. For example, we can define -- --
-- putStrLnWithCallStack :: HasCallStack => String -> IO () ---- -- as a variant of putStrLn that will get its call-site and -- print it, along with the string given as argument. We can access the -- call-stack inside putStrLnWithCallStack with -- callStack. -- --
-- putStrLnWithCallStack :: HasCallStack => String -> IO () -- putStrLnWithCallStack msg = do -- putStrLn msg -- putStrLn (prettyCallStack callStack) ---- -- Thus, if we call putStrLnWithCallStack we will get a -- formatted call-stack alongside our string. -- --
-- >>> putStrLnWithCallStack "hello" -- hello -- CallStack (from HasCallStack): -- putStrLnWithCallStack, called at <interactive>:2:1 in interactive:Ghci1 ---- -- GHC solves HasCallStack constraints in three steps: -- --
-- id x = x --id :: a -> a -- | Case analysis for the Either type. If the value is -- Left a, apply the first function to a; if it -- is Right b, apply the second function to b. -- --
-- >>> let s = Left "foo" :: Either String Int -- -- >>> let n = Right 3 :: Either String Int -- -- >>> either length (*2) s -- 3 -- -- >>> either length (*2) n -- 6 --either :: (a -> c) -> (b -> c) -> Either a b -> c -- | See examples in Control.Monad.Reader. Note, the partially -- applied function type (->) r is a simple reader monad. See -- the instance declaration below. class Monad m => MonadReader r (m :: Type -> Type) | m -> r -- | Retrieves the monad environment. ask :: MonadReader r m => m r -- | Executes a computation in a modified environment. local :: MonadReader r m => (r -> r) -> m a -> m a -- | Retrieves a function of the current environment. reader :: MonadReader r m => (r -> a) -> m a -- | Minimal definition is either both of get and put or -- just state class Monad m => MonadState s (m :: Type -> Type) | m -> s -- | Replace the state inside the monad. put :: MonadState s m => s -> m () -- | Embed a simple state action into the monad. state :: MonadState s m => (s -> (a, s)) -> m a -- | A space-efficient representation of a Word8 vector, supporting -- many efficient operations. -- -- A ByteString contains 8-bit bytes, or by using the operations -- from Data.ByteString.Char8 it can be interpreted as containing -- 8-bit characters. data ByteString -- | An infix synonym for fmap. -- -- The name of this operator is an allusion to $. Note the -- similarities between their types: -- --
-- ($) :: (a -> b) -> a -> b -- (<$>) :: Functor f => (a -> b) -> f a -> f b ---- -- Whereas $ is function application, <$> is function -- application lifted over a Functor. -- --
-- >>> show <$> Nothing -- Nothing -- -- >>> show <$> Just 3 -- Just "3" ---- -- Convert from an Either Int Int to an -- Either Int String using show: -- --
-- >>> show <$> Left 17 -- Left 17 -- -- >>> show <$> Right 17 -- Right "17" ---- -- Double each element of a list: -- --
-- >>> (*2) <$> [1,2,3] -- [2,4,6] ---- -- Apply even to the second element of a pair: -- --
-- >>> even <$> (2,2) -- (2,True) --(<$>) :: Functor f => (a -> b) -> f a -> f b infixl 4 <$> -- | A String is a list of characters. String constants in Haskell -- are values of type String. type String = [Char] -- | The class of types that can be converted to a hash value. -- -- Minimal implementation: hashWithSalt. class Hashable a -- | Return a hash value for the argument, using the given salt. -- -- The general contract of hashWithSalt is: -- --
-- >>> const 42 "hello" -- 42 ---- --
-- >>> map (const 42) [0..3] -- [42,42,42,42] --const :: a -> b -> a -- | Function composition. (.) :: (b -> c) -> (a -> b) -> a -> c infixr 9 . -- | A map from keys to values. A map cannot contain duplicate keys; each -- key can map to at most one value. data HashMap k v -- | A Map from keys k to values a. -- -- The Semigroup operation for Map is union, which -- prefers values from the left operand. If m1 maps a key -- k to a value a1, and m2 maps the same key -- to a different value a2, then their union m1 <> -- m2 maps k to a1. data Map k a -- | A handle managing output to the Haskell program's standard output -- channel. stdout :: Handle -- | Haskell defines operations to read and write characters from and to -- files, represented by values of type Handle. Each value of -- this type is a handle: a record used by the Haskell run-time -- system to manage I/O with file system objects. A handle has at -- least the following properties: -- --
-- mzero >>= f = mzero -- v >> mzero = mzero ---- -- The default definition is -- --
-- mzero = empty --mzero :: MonadPlus m => m a -- | An associative operation. The default definition is -- --
-- mplus = (<|>) --mplus :: MonadPlus m => m a -> m a -> m a -- | Right-to-left composition of functors. The composition of applicative -- functors is always applicative, but the composition of monads is not -- always a monad. newtype Compose (f :: k -> Type) (g :: k1 -> k) (a :: k1) Compose :: f (g a) -> Compose (f :: k -> Type) (g :: k1 -> k) (a :: k1) [getCompose] :: Compose (f :: k -> Type) (g :: k1 -> k) (a :: k1) -> f (g a) infixr 9 `Compose` infixr 9 `Compose` -- | If Void is uninhabited then any Functor that holds only -- values of type Void is holding no values. vacuous :: Functor f => f Void -> f a -- | Since Void values logically don't exist, this witnesses the -- logical reasoning tool of "ex falso quodlibet". -- --
-- >>> let x :: Either Void Int; x = Right 5
--
-- >>> :{
-- case x of
-- Right r -> r
-- Left l -> absurd l
-- :}
-- 5
--
absurd :: Void -> a
-- | Uninhabited data type
data Void
-- | Repeat a value n times.
--
-- -- mtimesDefault n a = a <> a <> ... <> a -- using <> (n-1) times ---- -- Implemented using stimes and mempty. -- -- This is a suitable definition for an mtimes member of -- Monoid. mtimesDefault :: (Integral b, Monoid a) => b -> a -> a -- | A generalization of cycle to an arbitrary Semigroup. May -- fail to terminate for some values in some semigroups. cycle1 :: Semigroup m => m -> m -- | Provide a Semigroup for an arbitrary Monoid. -- -- NOTE: This is not needed anymore since Semigroup became -- a superclass of Monoid in base-4.11 and this newtype be -- deprecated at some point in the future. data WrappedMonoid m -- | Option is effectively Maybe with a better instance of -- Monoid, built off of an underlying Semigroup instead of -- an underlying Monoid. -- -- Ideally, this type would not exist at all and we would just fix the -- Monoid instance of Maybe. -- -- In GHC 8.4 and higher, the Monoid instance for Maybe has -- been corrected to lift a Semigroup instance instead of a -- Monoid instance. Consequently, this type is no longer useful. -- It will be marked deprecated in GHC 8.8 and removed in GHC 8.10. newtype Option a Option :: Maybe a -> Option a [getOption] :: Option a -> Maybe a -- | The sortWith function sorts a list of elements using the user -- supplied function to project something out of each element sortWith :: Ord b => (a -> b) -> [a] -> [a] -- | A bifunctor is a type constructor that takes two type arguments and is -- a functor in both arguments. That is, unlike with -- Functor, a type constructor such as Either does not need -- to be partially applied for a Bifunctor instance, and the -- methods in this class permit mapping functions over the Left -- value or the Right value, or both at the same time. -- -- Formally, the class Bifunctor represents a bifunctor from -- Hask -> Hask. -- -- Intuitively it is a bifunctor where both the first and second -- arguments are covariant. -- -- You can define a Bifunctor by either defining bimap or -- by defining both first and second. -- -- If you supply bimap, you should ensure that: -- --
-- bimap id id ≡ id ---- -- If you supply first and second, ensure: -- --
-- first id ≡ id -- second id ≡ id ---- -- If you supply both, you should also ensure: -- --
-- bimap f g ≡ first f . second g ---- -- These ensure by parametricity: -- --
-- bimap (f . g) (h . i) ≡ bimap f h . bimap g i -- first (f . g) ≡ first f . first g -- second (f . g) ≡ second f . second g --class Bifunctor (p :: Type -> Type -> Type) -- | Map over both arguments at the same time. -- --
-- bimap f g ≡ first f . second g ---- --
-- >>> bimap toUpper (+1) ('j', 3)
-- ('J',4)
--
--
-- -- >>> bimap toUpper (+1) (Left 'j') -- Left 'J' ---- --
-- >>> bimap toUpper (+1) (Right 3) -- Right 4 --bimap :: Bifunctor p => (a -> b) -> (c -> d) -> p a c -> p b d -- | Map covariantly over the first argument. -- --
-- first f ≡ bimap f id ---- --
-- >>> first toUpper ('j', 3)
-- ('J',3)
--
--
-- -- >>> first toUpper (Left 'j') -- Left 'J' --first :: Bifunctor p => (a -> b) -> p a c -> p b c -- | Map covariantly over the second argument. -- --
-- second ≡ bimap id ---- --
-- >>> second (+1) ('j', 3)
-- ('j',4)
--
--
-- -- >>> second (+1) (Right 3) -- Right 4 --second :: Bifunctor p => (b -> c) -> p a b -> p a c -- | Extract everything except the last element of the stream. init :: NonEmpty a -> [a] -- | Extract the last element of the stream. last :: NonEmpty a -> a -- | Extract the possibly-empty tail of the stream. tail :: NonEmpty a -> [a] -- | Extract the first element of the stream. head :: NonEmpty a -> a -- | nonEmpty efficiently turns a normal list into a NonEmpty -- stream, producing Nothing if the input is empty. nonEmpty :: [a] -> Maybe (NonEmpty a) -- | Get a string representation of the current execution stack state. showStackTrace :: IO (Maybe String) -- | Get a trace of the current execution stack state. -- -- Returns Nothing if stack trace support isn't available on -- host machine. getStackTrace :: IO (Maybe [Location]) -- | Monads in which IO computations may be embedded. Any monad -- built by applying a sequence of monad transformers to the IO -- monad will be an instance of this class. -- -- Instances should satisfy the following laws, which state that -- liftIO is a transformer of monads: -- -- class Monad m => MonadIO (m :: Type -> Type) -- | Lift a computation from the IO monad. liftIO :: MonadIO m => IO a -> m a -- | Direct MonadPlus equivalent of filter. -- --
-- filter = ( mfilter :: (a -> Bool) -> [a] -> [a] ) ---- -- An example using mfilter with the Maybe monad: -- --
-- >>> mfilter odd (Just 1) -- Just 1 -- >>> mfilter odd (Just 2) -- Nothing --mfilter :: MonadPlus m => (a -> Bool) -> m a -> m a -- | Strict version of <$>. (<$!>) :: Monad m => (a -> b) -> m a -> m b infixl 4 <$!> -- | Like replicateM, but discards the result. replicateM_ :: Applicative m => Int -> m a -> m () -- | replicateM n act performs the action n times, -- gathering the results. replicateM :: Applicative m => Int -> m a -> m [a] -- | Like foldM, but discards the result. foldM_ :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m () -- | The foldM function is analogous to foldl, except that -- its result is encapsulated in a monad. Note that foldM works -- from left-to-right over the list arguments. This could be an issue -- where (>>) and the `folded function' are not -- commutative. -- --
-- foldM f a1 [x1, x2, ..., xm] -- -- == -- -- do -- a2 <- f a1 x1 -- a3 <- f a2 x2 -- ... -- f am xm ---- -- If right-to-left evaluation is required, the input list should be -- reversed. -- -- Note: foldM is the same as foldlM foldM :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b -- | zipWithM_ is the extension of zipWithM which ignores the -- final result. zipWithM_ :: Applicative m => (a -> b -> m c) -> [a] -> [b] -> m () -- | The zipWithM function generalizes zipWith to arbitrary -- applicative functors. zipWithM :: Applicative m => (a -> b -> m c) -> [a] -> [b] -> m [c] -- | The mapAndUnzipM function maps its first argument over a list, -- returning the result as a pair of lists. This function is mainly used -- with complicated data structures or a state monad. mapAndUnzipM :: Applicative m => (a -> m (b, c)) -> [a] -> m ([b], [c]) -- | Repeat an action indefinitely. -- --
-- echoServer :: Socket -> IO () -- echoServer socket = forever $ do -- client <- accept socket -- forkFinally (echo client) (\_ -> hClose client) -- where -- echo :: Handle -> IO () -- echo client = forever $ -- hGetLine client >>= hPutStrLn client --forever :: Applicative f => f a -> f b -- | Right-to-left composition of Kleisli arrows. -- (>=>), with the arguments flipped. -- -- Note how this operator resembles function composition -- (.): -- --
-- (.) :: (b -> c) -> (a -> b) -> a -> c -- (<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c --(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c infixr 1 <=< -- | Left-to-right composition of Kleisli arrows. (>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c infixr 1 >=> -- | This generalizes the list-based filter function. filterM :: Applicative m => (a -> m Bool) -> [a] -> m [a] -- | This function may be used as a value for foldMap in a -- Foldable instance. -- --
-- foldMapDefault f ≡ getConst . traverse (Const . f) --foldMapDefault :: (Traversable t, Monoid m) => (a -> m) -> t a -> m -- | This function may be used as a value for fmap in a -- Functor instance, provided that traverse is defined. -- (Using fmapDefault with a Traversable instance defined -- only by sequenceA will result in infinite recursion.) -- --
-- fmapDefault f ≡ runIdentity . traverse (Identity . f) --fmapDefault :: Traversable t => (a -> b) -> t a -> t b -- | The mapAccumR function behaves like a combination of -- fmap and foldr; it applies a function to each element of -- a structure, passing an accumulating parameter from right to left, and -- returning a final value of this accumulator together with the new -- structure. mapAccumR :: Traversable t => (a -> b -> (a, c)) -> a -> t b -> (a, t c) -- | The mapAccumL function behaves like a combination of -- fmap and foldl; it applies a function to each element of -- a structure, passing an accumulating parameter from left to right, and -- returning a final value of this accumulator together with the new -- structure. mapAccumL :: Traversable t => (a -> b -> (a, c)) -> a -> t b -> (a, t c) -- | forM is mapM with its arguments flipped. For a version -- that ignores the results see forM_. forM :: (Traversable t, Monad m) => t a -> (a -> m b) -> m (t b) -- | One or none. optional :: Alternative f => f a -> f (Maybe a) -- | Lists, but with an Applicative functor based on zipping. newtype ZipList a ZipList :: [a] -> ZipList a [getZipList] :: ZipList a -> [a] -- | Fanout: send the input to both argument arrows and combine their -- output. -- -- The default definition may be overridden with a more efficient version -- if desired. (&&&) :: Arrow a => a b c -> a b c' -> a b (c, c') infixr 3 &&& -- | Identity functor and monad. (a non-strict monad) newtype Identity a Identity :: a -> Identity a [runIdentity] :: Identity a -> a -- | A handle managing output to the Haskell program's standard error -- channel. stderr :: Handle -- | A handle managing input from the Haskell program's standard input -- channel. stdin :: Handle -- | Perform some computation without adding new entries to the -- CallStack. withFrozenCallStack :: HasCallStack => (HasCallStack => a) -> a -- | Return the current CallStack. -- -- Does *not* include the call-site of callStack. callStack :: HasCallStack => CallStack -- | Write the supplied value into a TVar. writeTVar :: TVar a -> a -> STM () -- | Return the current value stored in a TVar. readTVar :: TVar a -> STM a -- | Create a new TVar holding a value supplied newTVar :: a -> STM (TVar a) -- | A monad supporting atomic memory transactions. data STM a -- | Shared memory locations that support atomic memory transactions. data TVar a -- | A mutable variable in the IO monad data IORef a -- | File and directory names are values of type String, whose -- precise meaning is operating system dependent. Files can be opened, -- yielding a handle which can then be used to operate on the contents of -- that file. type FilePath = String -- | Pretty print a CallStack. prettyCallStack :: CallStack -> String -- | Pretty print a SrcLoc. prettySrcLoc :: SrcLoc -> String -- | Any type that you wish to throw or catch as an exception must be an -- instance of the Exception class. The simplest case is a new -- exception type directly below the root: -- --
-- data MyException = ThisException | ThatException -- deriving Show -- -- instance Exception MyException ---- -- The default method definitions in the Exception class do what -- we need in this case. You can now throw and catch -- ThisException and ThatException as exceptions: -- --
-- *Main> throw ThisException `catch` \e -> putStrLn ("Caught " ++ show (e :: MyException))
-- Caught ThisException
--
--
-- In more complicated examples, you may wish to define a whole hierarchy
-- of exceptions:
--
-- -- --------------------------------------------------------------------- -- -- Make the root exception type for all the exceptions in a compiler -- -- data SomeCompilerException = forall e . Exception e => SomeCompilerException e -- -- instance Show SomeCompilerException where -- show (SomeCompilerException e) = show e -- -- instance Exception SomeCompilerException -- -- compilerExceptionToException :: Exception e => e -> SomeException -- compilerExceptionToException = toException . SomeCompilerException -- -- compilerExceptionFromException :: Exception e => SomeException -> Maybe e -- compilerExceptionFromException x = do -- SomeCompilerException a <- fromException x -- cast a -- -- --------------------------------------------------------------------- -- -- Make a subhierarchy for exceptions in the frontend of the compiler -- -- data SomeFrontendException = forall e . Exception e => SomeFrontendException e -- -- instance Show SomeFrontendException where -- show (SomeFrontendException e) = show e -- -- instance Exception SomeFrontendException where -- toException = compilerExceptionToException -- fromException = compilerExceptionFromException -- -- frontendExceptionToException :: Exception e => e -> SomeException -- frontendExceptionToException = toException . SomeFrontendException -- -- frontendExceptionFromException :: Exception e => SomeException -> Maybe e -- frontendExceptionFromException x = do -- SomeFrontendException a <- fromException x -- cast a -- -- --------------------------------------------------------------------- -- -- Make an exception type for a particular frontend compiler exception -- -- data MismatchedParentheses = MismatchedParentheses -- deriving Show -- -- instance Exception MismatchedParentheses where -- toException = frontendExceptionToException -- fromException = frontendExceptionFromException ---- -- We can now catch a MismatchedParentheses exception as -- MismatchedParentheses, SomeFrontendException or -- SomeCompilerException, but not other types, e.g. -- IOException: -- --
-- *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: MismatchedParentheses))
-- Caught MismatchedParentheses
-- *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: SomeFrontendException))
-- Caught MismatchedParentheses
-- *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: SomeCompilerException))
-- Caught MismatchedParentheses
-- *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: IOException))
-- *** Exception: MismatchedParentheses
--
class (Typeable e, Show e) => Exception e
toException :: Exception e => e -> SomeException
fromException :: Exception e => SomeException -> Maybe e
-- | Render this exception value in a human-friendly manner.
--
-- Default implementation: show.
displayException :: Exception e => e -> String
-- | The Const functor.
newtype Const a (b :: k)
Const :: a -> Const a (b :: k)
[getConst] :: Const a (b :: k) -> a
-- | The least element of a non-empty structure with respect to the given
-- comparison function.
minimumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a
-- | The largest element of a non-empty structure with respect to the given
-- comparison function.
maximumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a
-- | Map a function over all the elements of a container and concatenate
-- the resulting lists.
concatMap :: Foldable t => (a -> [b]) -> t a -> [b]
-- | Monadic fold over the elements of a structure, associating to the
-- left, i.e. from left to right.
foldlM :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b
-- | Monadic fold over the elements of a structure, associating to the
-- right, i.e. from right to left.
foldrM :: (Foldable t, Monad m) => (a -> b -> m b) -> b -> t a -> m b
-- | Maybe monoid returning the leftmost non-Nothing value.
--
-- First a is isomorphic to Alt Maybe
-- a, but precedes it historically.
--
-- -- >>> getFirst (First (Just "hello") <> First Nothing <> First (Just "world")) -- Just "hello" ---- -- Use of this type is discouraged. Note the following equivalence: -- --
-- Data.Monoid.First x === Maybe (Data.Semigroup.First x) ---- -- In addition to being equivalent in the structural sense, the two also -- have Monoid instances that behave the same. This type will be -- marked deprecated in GHC 8.8, and removed in GHC 8.10. Users are -- advised to use the variant from Data.Semigroup and wrap it in -- Maybe. newtype First a First :: Maybe a -> First a [getFirst] :: First a -> Maybe a -- | Maybe monoid returning the rightmost non-Nothing value. -- -- Last a is isomorphic to Dual (First -- a), and thus to Dual (Alt Maybe a) -- --
-- >>> getLast (Last (Just "hello") <> Last Nothing <> Last (Just "world")) -- Just "world" ---- -- Use of this type is discouraged. Note the following equivalence: -- --
-- Data.Monoid.Last x === Maybe (Data.Semigroup.Last x) ---- -- In addition to being equivalent in the structural sense, the two also -- have Monoid instances that behave the same. This type will be -- marked deprecated in GHC 8.8, and removed in GHC 8.10. Users are -- advised to use the variant from Data.Semigroup and wrap it in -- Maybe. newtype Last a Last :: Maybe a -> Last a [getLast] :: Last a -> Maybe a -- | This is a valid definition of stimes for a Monoid. -- -- Unlike the default definition of stimes, it is defined for 0 -- and so it should be preferred where possible. stimesMonoid :: (Integral b, Monoid a) => b -> a -> a -- | This is a valid definition of stimes for an idempotent -- Semigroup. -- -- When x <> x = x, this definition should be preferred, -- because it works in O(1) rather than O(log n). stimesIdempotent :: Integral b => b -> a -> a -- | The dual of a Monoid, obtained by swapping the arguments of -- mappend. -- --
-- >>> getDual (mappend (Dual "Hello") (Dual "World")) -- "WorldHello" --newtype Dual a Dual :: a -> Dual a [getDual] :: Dual a -> a -- | The monoid of endomorphisms under composition. -- --
-- >>> let computation = Endo ("Hello, " ++) <> Endo (++ "!")
--
-- >>> appEndo computation "Haskell"
-- "Hello, Haskell!"
--
newtype Endo a
Endo :: (a -> a) -> Endo a
[appEndo] :: Endo a -> a -> a
-- | Boolean monoid under conjunction (&&).
--
-- -- >>> getAll (All True <> mempty <> All False) -- False ---- --
-- >>> getAll (mconcat (map (\x -> All (even x)) [2,4,6,7,8])) -- False --newtype All All :: Bool -> All [getAll] :: All -> Bool -- | Boolean monoid under disjunction (||). -- --
-- >>> getAny (Any True <> mempty <> Any False) -- True ---- --
-- >>> getAny (mconcat (map (\x -> Any (even x)) [2,4,6,7,8])) -- True --newtype Any Any :: Bool -> Any [getAny] :: Any -> Bool -- | Monoid under addition. -- --
-- >>> getSum (Sum 1 <> Sum 2 <> mempty) -- 3 --newtype Sum a Sum :: a -> Sum a [getSum] :: Sum a -> a -- | Monoid under multiplication. -- --
-- >>> getProduct (Product 3 <> Product 4 <> mempty) -- 12 --newtype Product a Product :: a -> Product a [getProduct] :: Product a -> a -- | Monoid under <|>. newtype Alt (f :: k -> Type) (a :: k) Alt :: f a -> Alt (f :: k -> Type) (a :: k) [getAlt] :: Alt (f :: k -> Type) (a :: k) -> f a -- | Convert an integer into an unknown type-level natural. someNatVal :: Natural -> SomeNat natVal :: forall (n :: Nat) proxy. KnownNat n => proxy n -> Natural -- | This type represents unknown type-level natural numbers. data SomeNat SomeNat :: Proxy n -> SomeNat -- | The unfoldr function is a `dual' to foldr: while -- foldr reduces a list to a summary value, unfoldr builds -- a list from a seed value. The function takes the element and returns -- Nothing if it is done producing the list or returns Just -- (a,b), in which case, a is a prepended to the list -- and b is used as the next element in a recursive call. For -- example, -- --
-- iterate f == unfoldr (\x -> Just (x, f x)) ---- -- In some cases, unfoldr can undo a foldr operation: -- --
-- unfoldr f' (foldr f z xs) == xs ---- -- if the following holds: -- --
-- f' (f x y) = Just (x,y) -- f' z = Nothing ---- -- A simple use of unfoldr: -- --
-- >>> unfoldr (\b -> if b == 0 then Nothing else Just (b, b-1)) 10 -- [10,9,8,7,6,5,4,3,2,1] --unfoldr :: (b -> Maybe (a, b)) -> b -> [a] -- | Sort a list by comparing the results of a key function applied to each -- element. sortOn f is equivalent to sortBy (comparing -- f), but has the performance advantage of only evaluating -- f once for each element in the input list. This is called the -- decorate-sort-undecorate paradigm, or Schwartzian transform. -- -- Elements are arranged from from lowest to highest, keeping duplicates -- in the order they appeared in the input. -- --
-- >>> sortOn fst [(2, "world"), (4, "!"), (1, "Hello")] -- [(1,"Hello"),(2,"world"),(4,"!")] --sortOn :: Ord b => (a -> b) -> [a] -> [a] -- | The sortBy function is the non-overloaded version of -- sort. -- --
-- >>> sortBy (\(a,_) (b,_) -> compare a b) [(2, "world"), (4, "!"), (1, "Hello")] -- [(1,"Hello"),(2,"world"),(4,"!")] --sortBy :: (a -> a -> Ordering) -> [a] -> [a] -- | The sort function implements a stable sorting algorithm. It is -- a special case of sortBy, which allows the programmer to supply -- their own comparison function. -- -- Elements are arranged from from lowest to highest, keeping duplicates -- in the order they appeared in the input. -- --
-- >>> sort [1,6,4,3,2,5] -- [1,2,3,4,5,6] --sort :: Ord a => [a] -> [a] -- | The permutations function returns the list of all permutations -- of the argument. -- --
-- >>> permutations "abc" -- ["abc","bac","cba","bca","cab","acb"] --permutations :: [a] -> [[a]] -- | The subsequences function returns the list of all subsequences -- of the argument. -- --
-- >>> subsequences "abc" -- ["","a","b","ab","c","ac","bc","abc"] --subsequences :: [a] -> [[a]] -- | O(n). The tails function returns all final segments of -- the argument, longest first. For example, -- --
-- >>> tails "abc" -- ["abc","bc","c",""] ---- -- Note that tails has the following strictness property: -- tails _|_ = _|_ : _|_ tails :: [a] -> [[a]] -- | The inits function returns all initial segments of the -- argument, shortest first. For example, -- --
-- >>> inits "abc" -- ["","a","ab","abc"] ---- -- Note that inits has the following strictness property: -- inits (xs ++ _|_) = inits xs ++ _|_ -- -- In particular, inits _|_ = [] : _|_ inits :: [a] -> [[a]] -- | The group function takes a list and returns a list of lists -- such that the concatenation of the result is equal to the argument. -- Moreover, each sublist in the result contains only equal elements. For -- example, -- --
-- >>> group "Mississippi" -- ["M","i","ss","i","ss","i","pp","i"] ---- -- It is a special case of groupBy, which allows the programmer to -- supply their own equality test. group :: Eq a => [a] -> [[a]] -- | The genericReplicate function is an overloaded version of -- replicate, which accepts any Integral value as the -- number of repetitions to make. genericReplicate :: Integral i => i -> a -> [a] -- | The genericSplitAt function is an overloaded version of -- splitAt, which accepts any Integral value as the -- position at which to split. genericSplitAt :: Integral i => i -> [a] -> ([a], [a]) -- | The genericDrop function is an overloaded version of -- drop, which accepts any Integral value as the number of -- elements to drop. genericDrop :: Integral i => i -> [a] -> [a] -- | The genericTake function is an overloaded version of -- take, which accepts any Integral value as the number of -- elements to take. genericTake :: Integral i => i -> [a] -> [a] -- | O(n). The genericLength function is an overloaded -- version of length. In particular, instead of returning an -- Int, it returns any type which is an instance of Num. It -- is, however, less efficient than length. -- --
-- >>> genericLength [1, 2, 3] :: Int -- 3 -- -- >>> genericLength [1, 2, 3] :: Float -- 3.0 --genericLength :: Num i => [a] -> i -- | The transpose function transposes the rows and columns of its -- argument. For example, -- --
-- >>> transpose [[1,2,3],[4,5,6]] -- [[1,4],[2,5],[3,6]] ---- -- If some of the rows are shorter than the following rows, their -- elements are skipped: -- --
-- >>> transpose [[10,11],[20],[],[30,31,32]] -- [[10,20,30],[11,31],[32]] --transpose :: [[a]] -> [[a]] -- | intercalate xs xss is equivalent to (concat -- (intersperse xs xss)). It inserts the list xs in -- between the lists in xss and concatenates the result. -- --
-- >>> intercalate ", " ["Lorem", "ipsum", "dolor"] -- "Lorem, ipsum, dolor" --intercalate :: [a] -> [[a]] -> [a] -- | O(n). The intersperse function takes an element and a -- list and `intersperses' that element between the elements of the list. -- For example, -- --
-- >>> intersperse ',' "abcde" -- "a,b,c,d,e" --intersperse :: a -> [a] -> [a] -- | O(min(m,n)). The isPrefixOf function takes two lists and -- returns True iff the first list is a prefix of the second. -- --
-- >>> "Hello" `isPrefixOf` "Hello World!" -- True ---- --
-- >>> "Hello" `isPrefixOf` "Wello Horld!" -- False --isPrefixOf :: Eq a => [a] -> [a] -> Bool -- | Parse a string using the Read instance. Succeeds if there is -- exactly one valid result. -- --
-- >>> readMaybe "123" :: Maybe Int -- Just 123 ---- --
-- >>> readMaybe "hello" :: Maybe Int -- Nothing --readMaybe :: Read a => String -> Maybe a -- | equivalent to readsPrec with a precedence of 0. reads :: Read a => ReadS a -- | Return True if the given value is a Right-value, -- False otherwise. -- --
-- >>> isRight (Left "foo") -- False -- -- >>> isRight (Right 3) -- True ---- -- Assuming a Left value signifies some sort of error, we can use -- isRight to write a very simple reporting function that only -- outputs "SUCCESS" when a computation has succeeded. -- -- This example shows how isRight might be used to avoid pattern -- matching when one does not care about the value contained in the -- constructor: -- --
-- >>> import Control.Monad ( when ) -- -- >>> let report e = when (isRight e) $ putStrLn "SUCCESS" -- -- >>> report (Left "parse error") -- -- >>> report (Right 1) -- SUCCESS --isRight :: Either a b -> Bool -- | Return True if the given value is a Left-value, -- False otherwise. -- --
-- >>> isLeft (Left "foo") -- True -- -- >>> isLeft (Right 3) -- False ---- -- Assuming a Left value signifies some sort of error, we can use -- isLeft to write a very simple error-reporting function that -- does absolutely nothing in the case of success, and outputs "ERROR" if -- any error occurred. -- -- This example shows how isLeft might be used to avoid pattern -- matching when one does not care about the value contained in the -- constructor: -- --
-- >>> import Control.Monad ( when ) -- -- >>> let report e = when (isLeft e) $ putStrLn "ERROR" -- -- >>> report (Right 1) -- -- >>> report (Left "parse error") -- ERROR --isLeft :: Either a b -> Bool -- | Partitions a list of Either into two lists. All the Left -- elements are extracted, in order, to the first component of the -- output. Similarly the Right elements are extracted to the -- second component of the output. -- --
-- >>> let list = [ Left "foo", Right 3, Left "bar", Right 7, Left "baz" ] -- -- >>> partitionEithers list -- (["foo","bar","baz"],[3,7]) ---- -- The pair returned by partitionEithers x should be the -- same pair as (lefts x, rights x): -- --
-- >>> let list = [ Left "foo", Right 3, Left "bar", Right 7, Left "baz" ] -- -- >>> partitionEithers list == (lefts list, rights list) -- True --partitionEithers :: [Either a b] -> ([a], [b]) -- | Extracts from a list of Either all the Right elements. -- All the Right elements are extracted in order. -- --
-- >>> let list = [ Left "foo", Right 3, Left "bar", Right 7, Left "baz" ] -- -- >>> rights list -- [3,7] --rights :: [Either a b] -> [b] -- | Extracts from a list of Either all the Left elements. -- All the Left elements are extracted in order. -- --
-- >>> let list = [ Left "foo", Right 3, Left "bar", Right 7, Left "baz" ] -- -- >>> lefts list -- ["foo","bar","baz"] --lefts :: [Either a b] -> [a] -- |
-- comparing p x y = compare (p x) (p y) ---- -- Useful combinator for use in conjunction with the xxxBy -- family of functions from Data.List, for example: -- --
-- ... sortBy (comparing fst) ... --comparing :: Ord a => (b -> a) -> b -> b -> Ordering -- | The Down type allows you to reverse sort order conveniently. A -- value of type Down a contains a value of type -- a (represented as Down a). If a has -- an Ord instance associated with it then comparing two -- values thus wrapped will give you the opposite of their normal sort -- order. This is particularly useful when sorting in generalised list -- comprehensions, as in: then sortWith by Down x newtype Down a Down :: a -> Down a -- | Proxy is a type that holds no data, but has a phantom parameter -- of arbitrary type (or even kind). Its use is to provide type -- information, even though there is no value available of that type (or -- it may be too costly to create one). -- -- Historically, Proxy :: Proxy a is a safer -- alternative to the undefined :: a idiom. -- --
-- >>> Proxy :: Proxy (Void, Int -> Int) -- Proxy ---- -- Proxy can even hold types of higher kinds, -- --
-- >>> Proxy :: Proxy Either -- Proxy ---- --
-- >>> Proxy :: Proxy Functor -- Proxy ---- --
-- >>> Proxy :: Proxy complicatedStructure -- Proxy --data Proxy (t :: k) Proxy :: Proxy (t :: k) -- | See openFile data IOMode ReadMode :: IOMode WriteMode :: IOMode AppendMode :: IOMode ReadWriteMode :: IOMode -- | Reverse order of bytes in Word64. byteSwap64 :: Word64 -> Word64 -- | Reverse order of bytes in Word32. byteSwap32 :: Word32 -> Word32 -- | Swap bytes in Word16. byteSwap16 :: Word16 -> Word16 integralEnumFromThenTo :: Integral a => a -> a -> a -> [a] integralEnumFromTo :: Integral a => a -> a -> [a] integralEnumFromThen :: (Integral a, Bounded a) => a -> a -> [a] integralEnumFrom :: (Integral a, Bounded a) => a -> [a] gcdWord' :: Word -> Word -> Word gcdInt' :: Int -> Int -> Int -- | lcm x y is the smallest positive integer that both -- x and y divide. lcm :: Integral a => a -> a -> a -- | gcd x y is the non-negative factor of both x -- and y of which every common factor of x and -- y is also a factor; for example gcd 4 2 = 2, -- gcd (-4) 6 = 2, gcd 0 4 = 4. -- gcd 0 0 = 0. (That is, the common divisor -- that is "greatest" in the divisibility preordering.) -- -- Note: Since for signed fixed-width integer types, abs -- minBound < 0, the result may be negative if one of the -- arguments is minBound (and necessarily is if the other -- is 0 or minBound) for such types. gcd :: Integral a => a -> a -> a (^^%^^) :: Integral a => Rational -> a -> Rational (^%^) :: Integral a => Rational -> a -> Rational -- | raise a number to an integral power (^^) :: (Fractional a, Integral b) => a -> b -> a infixr 8 ^^ odd :: Integral a => a -> Bool even :: Integral a => a -> Bool numericEnumFromThenTo :: (Ord a, Fractional a) => a -> a -> a -> [a] numericEnumFromTo :: (Ord a, Fractional a) => a -> a -> [a] numericEnumFromThen :: Fractional a => a -> a -> [a] numericEnumFrom :: Fractional a => a -> [a] -- | Extract the denominator of the ratio in reduced form: the numerator -- and denominator have no common factor and the denominator is positive. denominator :: Ratio a -> a -- | Extract the numerator of the ratio in reduced form: the numerator and -- denominator have no common factor and the denominator is positive. numerator :: Ratio a -> a -- | reduce is a subsidiary function used only in this module. It -- normalises a ratio by dividing both numerator and denominator by their -- greatest common divisor. reduce :: Integral a => a -> a -> Ratio a notANumber :: Rational infinity :: Rational ratioPrec1 :: Int ratioPrec :: Int underflowError :: a overflowError :: a ratioZeroDenominatorError :: a divZeroError :: a boundedEnumFromThen :: (Enum a, Bounded a) => a -> a -> [a] boundedEnumFrom :: (Enum a, Bounded a) => a -> [a] -- | The toEnum method restricted to the type Char. chr :: Int -> Char -- | The unzip3 function takes a list of triples and returns three -- lists, analogous to unzip. unzip3 :: [(a, b, c)] -> ([a], [b], [c]) -- | unzip transforms a list of pairs into a list of first -- components and a list of second components. unzip :: [(a, b)] -> ([a], [b]) -- | O(min(m,n)). zipWith generalises zip by zipping -- with the function given as the first argument, instead of a tupling -- function. For example, zipWith (+) is applied to two -- lists to produce the list of corresponding sums: -- --
-- >>> zipWith (+) [1, 2, 3] [4, 5, 6] -- [5,7,9] ---- -- zipWith is right-lazy: -- --
-- zipWith f [] _|_ = [] ---- -- zipWith is capable of list fusion, but it is restricted to its -- first list argument and its resulting list. zipWith :: (a -> b -> c) -> [a] -> [b] -> [c] -- | zip3 takes three lists and returns a list of triples, analogous -- to zip. It is capable of list fusion, but it is restricted to -- its first list argument and its resulting list. zip3 :: [a] -> [b] -> [c] -> [(a, b, c)] -- | reverse xs returns the elements of xs in -- reverse order. xs must be finite. reverse :: [a] -> [a] -- | break, applied to a predicate p and a list -- xs, returns a tuple where first element is longest prefix -- (possibly empty) of xs of elements that do not satisfy -- p and second element is the remainder of the list: -- --
-- break (> 3) [1,2,3,4,1,2,3,4] == ([1,2,3],[4,1,2,3,4]) -- break (< 9) [1,2,3] == ([],[1,2,3]) -- break (> 9) [1,2,3] == ([1,2,3],[]) ---- -- break p is equivalent to span (not . -- p). break :: (a -> Bool) -> [a] -> ([a], [a]) -- | splitAt n xs returns a tuple where first element is -- xs prefix of length n and second element is the -- remainder of the list: -- --
-- splitAt 6 "Hello World!" == ("Hello ","World!")
-- splitAt 3 [1,2,3,4,5] == ([1,2,3],[4,5])
-- splitAt 1 [1,2,3] == ([1],[2,3])
-- splitAt 3 [1,2,3] == ([1,2,3],[])
-- splitAt 4 [1,2,3] == ([1,2,3],[])
-- splitAt 0 [1,2,3] == ([],[1,2,3])
-- splitAt (-1) [1,2,3] == ([],[1,2,3])
--
--
-- It is equivalent to (take n xs, drop n xs) when
-- n is not _|_ (splitAt _|_ xs = _|_).
-- splitAt is an instance of the more general
-- genericSplitAt, in which n may be of any integral
-- type.
splitAt :: Int -> [a] -> ([a], [a])
-- | drop n xs returns the suffix of xs after the
-- first n elements, or [] if n > length
-- xs:
--
-- -- drop 6 "Hello World!" == "World!" -- drop 3 [1,2,3,4,5] == [4,5] -- drop 3 [1,2] == [] -- drop 3 [] == [] -- drop (-1) [1,2] == [1,2] -- drop 0 [1,2] == [1,2] ---- -- It is an instance of the more general genericDrop, in which -- n may be of any integral type. drop :: Int -> [a] -> [a] -- | take n, applied to a list xs, returns the -- prefix of xs of length n, or xs itself if -- n > length xs: -- --
-- take 5 "Hello World!" == "Hello" -- take 3 [1,2,3,4,5] == [1,2,3] -- take 3 [1,2] == [1,2] -- take 3 [] == [] -- take (-1) [1,2] == [] -- take 0 [1,2] == [] ---- -- It is an instance of the more general genericTake, in which -- n may be of any integral type. take :: Int -> [a] -> [a] -- | dropWhile p xs returns the suffix remaining after -- takeWhile p xs: -- --
-- dropWhile (< 3) [1,2,3,4,5,1,2,3] == [3,4,5,1,2,3] -- dropWhile (< 9) [1,2,3] == [] -- dropWhile (< 0) [1,2,3] == [1,2,3] --dropWhile :: (a -> Bool) -> [a] -> [a] -- | takeWhile, applied to a predicate p and a list -- xs, returns the longest prefix (possibly empty) of -- xs of elements that satisfy p: -- --
-- takeWhile (< 3) [1,2,3,4,1,2,3,4] == [1,2] -- takeWhile (< 9) [1,2,3] == [1,2,3] -- takeWhile (< 0) [1,2,3] == [] --takeWhile :: (a -> Bool) -> [a] -> [a] -- | cycle ties a finite list into a circular one, or equivalently, -- the infinite repetition of the original list. It is the identity on -- infinite lists. cycle :: [a] -> [a] -- | replicate n x is a list of length n with -- x the value of every element. It is an instance of the more -- general genericReplicate, in which n may be of any -- integral type. replicate :: Int -> a -> [a] -- | repeat x is an infinite list, with x the -- value of every element. repeat :: a -> [a] -- | iterate f x returns an infinite list of repeated -- applications of f to x: -- --
-- iterate f x == [x, f x, f (f x), ...] ---- -- Note that iterate is lazy, potentially leading to thunk -- build-up if the consumer doesn't force each iterate. See -- iterate' for a strict variant of this function. iterate :: (a -> a) -> a -> [a] -- | O(n). scanr is the right-to-left dual of scanl. -- Note that -- --
-- head (scanr f z xs) == foldr f z xs. --scanr :: (a -> b -> b) -> b -> [a] -> [b] -- | O(n). scanl is similar to foldl, but returns a -- list of successive reduced values from the left: -- --
-- scanl f z [x1, x2, ...] == [z, z `f` x1, (z `f` x1) `f` x2, ...] ---- -- Note that -- --
-- last (scanl f z xs) == foldl f z xs. --scanl :: (b -> a -> b) -> b -> [a] -> [b] -- | The mapMaybe function is a version of map which can -- throw out elements. In particular, the functional argument returns -- something of type Maybe b. If this is Nothing, -- no element is added on to the result list. If it is Just -- b, then b is included in the result list. -- --
-- >>> import Text.Read ( readMaybe ) -- -- >>> let readMaybeInt = readMaybe :: String -> Maybe Int -- -- >>> mapMaybe readMaybeInt ["1", "Foo", "3"] -- [1,3] -- -- >>> catMaybes $ map readMaybeInt ["1", "Foo", "3"] -- [1,3] ---- -- If we map the Just constructor, the entire list should be -- returned: -- --
-- >>> mapMaybe Just [1,2,3] -- [1,2,3] --mapMaybe :: (a -> Maybe b) -> [a] -> [b] -- | The catMaybes function takes a list of Maybes and -- returns a list of all the Just values. -- --
-- >>> catMaybes [Just 1, Nothing, Just 3] -- [1,3] ---- -- When constructing a list of Maybe values, catMaybes can -- be used to return all of the "success" results (if the list is the -- result of a map, then mapMaybe would be more -- appropriate): -- --
-- >>> import Text.Read ( readMaybe ) -- -- >>> [readMaybe x :: Maybe Int | x <- ["1", "Foo", "3"] ] -- [Just 1,Nothing,Just 3] -- -- >>> catMaybes $ [readMaybe x :: Maybe Int | x <- ["1", "Foo", "3"] ] -- [1,3] --catMaybes :: [Maybe a] -> [a] -- | The listToMaybe function returns Nothing on an empty -- list or Just a where a is the first element -- of the list. -- --
-- >>> listToMaybe [] -- Nothing ---- --
-- >>> listToMaybe [9] -- Just 9 ---- --
-- >>> listToMaybe [1,2,3] -- Just 1 ---- -- Composing maybeToList with listToMaybe should be the -- identity on singleton/empty lists: -- --
-- >>> maybeToList $ listToMaybe [5] -- [5] -- -- >>> maybeToList $ listToMaybe [] -- [] ---- -- But not on lists with more than one element: -- --
-- >>> maybeToList $ listToMaybe [1,2,3] -- [1] --listToMaybe :: [a] -> Maybe a -- | The maybeToList function returns an empty list when given -- Nothing or a singleton list when given Just. -- --
-- >>> maybeToList (Just 7) -- [7] ---- --
-- >>> maybeToList Nothing -- [] ---- -- One can use maybeToList to avoid pattern matching when combined -- with a function that (safely) works on lists: -- --
-- >>> import Text.Read ( readMaybe ) -- -- >>> sum $ maybeToList (readMaybe "3") -- 3 -- -- >>> sum $ maybeToList (readMaybe "") -- 0 --maybeToList :: Maybe a -> [a] -- | The fromMaybe function takes a default value and and -- Maybe value. If the Maybe is Nothing, it returns -- the default values; otherwise, it returns the value contained in the -- Maybe. -- --
-- >>> fromMaybe "" (Just "Hello, World!") -- "Hello, World!" ---- --
-- >>> fromMaybe "" Nothing -- "" ---- -- Read an integer from a string using readMaybe. If we fail to -- parse an integer, we want to return 0 by default: -- --
-- >>> import Text.Read ( readMaybe ) -- -- >>> fromMaybe 0 (readMaybe "5") -- 5 -- -- >>> fromMaybe 0 (readMaybe "") -- 0 --fromMaybe :: a -> Maybe a -> a -- | The isNothing function returns True iff its argument is -- Nothing. -- --
-- >>> isNothing (Just 3) -- False ---- --
-- >>> isNothing (Just ()) -- False ---- --
-- >>> isNothing Nothing -- True ---- -- Only the outer constructor is taken into consideration: -- --
-- >>> isNothing (Just Nothing) -- False --isNothing :: Maybe a -> Bool -- | The isJust function returns True iff its argument is of -- the form Just _. -- --
-- >>> isJust (Just 3) -- True ---- --
-- >>> isJust (Just ()) -- True ---- --
-- >>> isJust Nothing -- False ---- -- Only the outer constructor is taken into consideration: -- --
-- >>> isJust (Just Nothing) -- True --isJust :: Maybe a -> Bool -- | The maybe function takes a default value, a function, and a -- Maybe value. If the Maybe value is Nothing, the -- function returns the default value. Otherwise, it applies the function -- to the value inside the Just and returns the result. -- --
-- >>> maybe False odd (Just 3) -- True ---- --
-- >>> maybe False odd Nothing -- False ---- -- Read an integer from a string using readMaybe. If we succeed, -- return twice the integer; that is, apply (*2) to it. If -- instead we fail to parse an integer, return 0 by default: -- --
-- >>> import Text.Read ( readMaybe ) -- -- >>> maybe 0 (*2) (readMaybe "5") -- 10 -- -- >>> maybe 0 (*2) (readMaybe "") -- 0 ---- -- Apply show to a Maybe Int. If we have Just n, -- we want to show the underlying Int n. But if we have -- Nothing, we return the empty string instead of (for example) -- "Nothing": -- --
-- >>> maybe "" show (Just 5) -- "5" -- -- >>> maybe "" show Nothing -- "" --maybe :: b -> (a -> b) -> Maybe a -> b -- | Case analysis for the Bool type. bool x y p -- evaluates to x when p is False, and evaluates -- to y when p is True. -- -- This is equivalent to if p then y else x; that is, one can -- think of it as an if-then-else construct with its arguments reordered. -- --
-- >>> bool "foo" "bar" True -- "bar" -- -- >>> bool "foo" "bar" False -- "foo" ---- -- Confirm that bool x y p and if p then y else -- x are equivalent: -- --
-- >>> let p = True; x = "bar"; y = "foo" -- -- >>> bool x y p == if p then y else x -- True -- -- >>> let p = False -- -- >>> bool x y p == if p then y else x -- True --bool :: a -> a -> Bool -> a -- | & is a reverse application operator. This provides -- notational convenience. Its precedence is one higher than that of the -- forward application operator $, which allows & to be -- nested in $. -- --
-- >>> 5 & (+1) & show -- "6" --(&) :: a -> (a -> b) -> b infixl 1 & -- | on b u x y runs the binary function b -- on the results of applying unary function u to two -- arguments x and y. From the opposite perspective, it -- transforms two inputs and combines the outputs. -- --
-- ((+) `on` f) x y = f x + f y ---- -- Typical usage: sortBy (compare `on` -- fst). -- -- Algebraic properties: -- --
(*) `on` id = (*) -- (if (*) ∉ {⊥, const -- ⊥})
((*) `on` f) `on` g = (*) `on` (f . g)
flip on f . flip on g = flip on (g . -- f)
-- >>> let fac n = if n <= 1 then 1 else n * fac (n-1) in fac 5 -- 120 ---- -- This uses the fact that Haskell’s let introduces recursive -- bindings. We can rewrite this definition using fix, -- --
-- >>> fix (\rec n -> if n <= 1 then 1 else n * rec (n-1)) 5 -- 120 ---- -- Instead of making a recursive call, we introduce a dummy parameter -- rec; when used within fix, this parameter then refers -- to fix argument, hence the recursion is reintroduced. fix :: (a -> a) -> a -- | void value discards or ignores the result of -- evaluation, such as the return value of an IO action. -- --
-- >>> void Nothing -- Nothing -- -- >>> void (Just 3) -- Just () ---- -- Replace the contents of an Either Int -- Int with unit, resulting in an Either -- Int (): -- --
-- >>> void (Left 8675309) -- Left 8675309 -- -- >>> void (Right 8675309) -- Right () ---- -- Replace every element of a list with unit: -- --
-- >>> void [1,2,3] -- [(),(),()] ---- -- Replace the second element of a pair with unit: -- --
-- >>> void (1,2) -- (1,()) ---- -- Discard the result of an IO action: -- --
-- >>> mapM print [1,2] -- 1 -- 2 -- [(),()] -- -- >>> void $ mapM print [1,2] -- 1 -- 2 --void :: Functor f => f a -> f () -- | Flipped version of <$. -- --
-- >>> Nothing $> "foo" -- Nothing -- -- >>> Just 90210 $> "foo" -- Just "foo" ---- -- Replace the contents of an Either Int -- Int with a constant String, resulting in an -- Either Int String: -- --
-- >>> Left 8675309 $> "foo" -- Left 8675309 -- -- >>> Right 8675309 $> "foo" -- Right "foo" ---- -- Replace each element of a list with a constant String: -- --
-- >>> [1,2,3] $> "foo" -- ["foo","foo","foo"] ---- -- Replace the second element of a pair with a constant String: -- --
-- >>> (1,2) $> "foo" -- (1,"foo") --($>) :: Functor f => f a -> b -> f b infixl 4 $> -- | Flipped version of <$>. -- --
-- (<&>) = flip fmap ---- --
-- >>> Just 2 <&> (+1) -- Just 3 ---- --
-- >>> [1,2,3] <&> (+1) -- [2,3,4] ---- --
-- >>> Right 3 <&> (+1) -- Right 4 --(<&>) :: Functor f => f a -> (a -> b) -> f b infixl 1 <&> -- | Swap the components of a pair. swap :: (a, b) -> (b, a) -- | uncurry converts a curried function to a function on pairs. -- --
-- >>> uncurry (+) (1,2) -- 3 ---- --
-- >>> uncurry ($) (show, 1) -- "1" ---- --
-- >>> map (uncurry max) [(1,2), (3,4), (6,8)] -- [2,4,8] --uncurry :: (a -> b -> c) -> (a, b) -> c -- | curry converts an uncurried function to a curried function. -- --
-- >>> curry fst 1 2 -- 1 --curry :: ((a, b) -> c) -> a -> b -> c -- | An MVar (pronounced "em-var") is a synchronising variable, used -- for communication between concurrent threads. It can be thought of as -- a box, which may be empty or full. data MVar a -- | the same as flip (-). -- -- Because - is treated specially in the Haskell grammar, -- (- e) is not a section, but an application of -- prefix negation. However, (subtract -- exp) is equivalent to the disallowed section. subtract :: Num a => a -> a -> a -- | Returns a [String] representing the current call stack. This -- can be useful for debugging. -- -- The implementation uses the call-stack simulation maintained by the -- profiler, so it only works if the program was compiled with -- -prof and contains suitable SCC annotations (e.g. by using -- -fprof-auto). Otherwise, the list returned is likely to be -- empty or uninformative. currentCallStack :: IO [String] -- | asTypeOf is a type-restricted version of const. It is -- usually used as an infix operator, and its typing forces its first -- argument (which is usually overloaded) to have the same type as the -- second. asTypeOf :: a -> a -> a -- | flip f takes its (first) two arguments in the reverse -- order of f. -- --
-- >>> flip (++) "hello" "world" -- "worldhello" --flip :: (a -> b -> c) -> b -> a -> c maxInt :: Int minInt :: Int -- | The fromEnum method restricted to the type Char. ord :: Char -> Int -- | In many situations, the liftM operations can be replaced by -- uses of ap, which promotes function application. -- --
-- return f `ap` x1 `ap` ... `ap` xn ---- -- is equivalent to -- --
-- liftMn f x1 x2 ... xn --ap :: Monad m => m (a -> b) -> m a -> m b -- | Promote a function to a monad, scanning the monadic arguments from -- left to right (cf. liftM2). liftM5 :: Monad m => (a1 -> a2 -> a3 -> a4 -> a5 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m a5 -> m r -- | Promote a function to a monad, scanning the monadic arguments from -- left to right (cf. liftM2). liftM4 :: Monad m => (a1 -> a2 -> a3 -> a4 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m r -- | Promote a function to a monad, scanning the monadic arguments from -- left to right (cf. liftM2). liftM3 :: Monad m => (a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r -- | Promote a function to a monad, scanning the monadic arguments from -- left to right. For example, -- --
-- liftM2 (+) [0,1] [0,2] = [0,2,1,3] -- liftM2 (+) (Just 1) Nothing = Nothing --liftM2 :: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r -- | Same as >>=, but with the arguments interchanged. (=<<) :: Monad m => (a -> m b) -> m a -> m b infixr 1 =<< -- | Lift a ternary function to actions. liftA3 :: Applicative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d -- | A variant of <*> with the arguments reversed. (<**>) :: Applicative f => f a -> f (a -> b) -> f b infixl 4 <**> -- | Non-empty (and non-strict) list type. data NonEmpty a (:|) :: a -> [a] -> NonEmpty a infixr 5 :| -- | Extract a list of call-sites from the CallStack. -- -- The list is ordered by most recent call. getCallStack :: CallStack -> [([Char], SrcLoc)] -- | Request a CallStack. -- -- NOTE: The implicit parameter ?callStack :: CallStack is an -- implementation detail and should not be considered part of the -- CallStack API, we may decide to change the implementation in -- the future. type HasCallStack = ?callStack :: CallStack -- | This is a valid definition of stimes for an idempotent -- Monoid. -- -- When mappend x x = x, this definition should be preferred, -- because it works in O(1) rather than O(log n) stimesIdempotentMonoid :: (Integral b, Monoid a) => b -> a -> a -- | The SomeException type is the root of the exception type -- hierarchy. When an exception of type e is thrown, behind the -- scenes it is encapsulated in a SomeException. data SomeException SomeException :: e -> SomeException -- | The trivial monad transformer, which maps a monad to an equivalent -- monad. data IdentityT (f :: k -> Type) (a :: k) -- | From a Dict, takes a value in an environment where the instance -- witnessed by the Dict is in scope, and evaluates it. -- -- Essentially a deconstruction of a Dict into its -- continuation-style form. -- -- Can also be used to deconstruct an entailment, a :- b, -- using a context a. -- --
-- withDict :: Dict c -> (c => r) -> r -- withDict :: a => (a :- c) -> (c => r) -> r --withDict :: HasDict c e => e -> (c => r) -> r -- | A map of integers to values a. data IntMap a -- | A set of integers. data IntSet -- | General-purpose finite sequences. data Seq a -- | A set of values a. data Set a -- | A class of types that can be fully evaluated. class NFData a -- | rnf should reduce its argument to normal form (that is, fully -- evaluate all sub-components), and then return (). -- --
-- {-# LANGUAGE DeriveGeneric #-}
--
-- import GHC.Generics (Generic, Generic1)
-- import Control.DeepSeq
--
-- data Foo a = Foo a String
-- deriving (Eq, Generic, Generic1)
--
-- instance NFData a => NFData (Foo a)
-- instance NFData1 Foo
--
-- data Colour = Red | Green | Blue
-- deriving Generic
--
-- instance NFData Colour
--
--
-- Starting with GHC 7.10, the example above can be written more
-- concisely by enabling the new DeriveAnyClass extension:
--
--
-- {-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}
--
-- import GHC.Generics (Generic)
-- import Control.DeepSeq
--
-- data Foo a = Foo a String
-- deriving (Eq, Generic, Generic1, NFData, NFData1)
--
-- data Colour = Red | Green | Blue
-- deriving (Generic, NFData)
--
--
-- -- rnf a = seq a () ---- -- However, starting with deepseq-1.4.0.0, the default -- implementation is based on DefaultSignatures allowing for -- more accurate auto-derived NFData instances. If you need the -- previously used exact default rnf method implementation -- semantics, use -- --
-- instance NFData Colour where rnf x = seq x () ---- -- or alternatively -- --
-- instance NFData Colour where rnf = rwhnf ---- -- or -- --
-- {-# LANGUAGE BangPatterns #-}
-- instance NFData Colour where rnf !_ = ()
--
rnf :: NFData a => a -> ()
-- | A class for types with a default value.
class Default a
-- | The default value for this type.
def :: Default a => a
-- | a variant of deepseq that is useful in some circumstances:
--
-- -- force x = x `deepseq` x ---- -- force x fully evaluates x, and then returns it. Note -- that force x only performs evaluation when the value of -- force x itself is demanded, so essentially it turns shallow -- evaluation into deep evaluation. -- -- force can be conveniently used in combination with -- ViewPatterns: -- --
-- {-# LANGUAGE BangPatterns, ViewPatterns #-}
-- import Control.DeepSeq
--
-- someFun :: ComplexData -> SomeResult
-- someFun (force -> !arg) = {- 'arg' will be fully evaluated -}
--
--
-- Another useful application is to combine force with
-- evaluate in order to force deep evaluation relative to other
-- IO operations:
--
--
-- import Control.Exception (evaluate)
-- import Control.DeepSeq
--
-- main = do
-- result <- evaluate $ force $ pureComputation
-- {- 'result' will be fully evaluated at this point -}
-- return ()
--
--
-- Finally, here's an exception safe variant of the readFile'
-- example:
--
-- -- readFile' :: FilePath -> IO String -- readFile' fn = bracket (openFile fn ReadMode) hClose $ \h -> -- evaluate . force =<< hGetContents h --force :: NFData a => a -> a -- | the deep analogue of $!. In the expression f $!! x, -- x is fully evaluated before the function f is -- applied to it. ($!!) :: NFData a => (a -> b) -> a -> b infixr 0 $!! -- | deepseq: fully evaluates the first argument, before returning -- the second. -- -- The name deepseq is used to illustrate the relationship to -- seq: where seq is shallow in the sense that it only -- evaluates the top level of its argument, deepseq traverses the -- entire data structure evaluating it completely. -- -- deepseq can be useful for forcing pending exceptions, -- eradicating space leaks, or forcing lazy I/O to happen. It is also -- useful in conjunction with parallel Strategies (see the -- parallel package). -- -- There is no guarantee about the ordering of evaluation. The -- implementation may evaluate the components of the structure in any -- order or in parallel. To impose an actual order on evaluation, use -- pseq from Control.Parallel in the parallel -- package. deepseq :: NFData a => a -> b -> b -- | The parameterizable maybe monad, obtained by composing an arbitrary -- monad with the Maybe monad. -- -- Computations are actions that may produce a value or exit. -- -- The return function yields a computation that produces that -- value, while >>= sequences two subcomputations, exiting -- if either computation does. newtype MaybeT (m :: Type -> Type) a MaybeT :: m (Maybe a) -> MaybeT (m :: Type -> Type) a [runMaybeT] :: MaybeT (m :: Type -> Type) a -> m (Maybe a) -- | A monad transformer that adds exceptions to other monads. -- -- ExceptT constructs a monad parameterized over two things: -- --
-- throwM e >> x = throwM e ---- -- In other words, throwing an exception short-circuits the rest of the -- monadic computation. class Monad m => MonadThrow (m :: Type -> Type) -- | A class for monads which allow exceptions to be caught, in particular -- exceptions which were thrown by throwM. -- -- Instances should obey the following law: -- --
-- catch (throwM e) f = f e ---- -- Note that the ability to catch an exception does not guarantee -- that we can deal with all possible exit points from a computation. -- Some monads, such as continuation-based stacks, allow for more than -- just a success/failure strategy, and therefore catch -- cannot be used by those monads to properly implement a function -- such as finally. For more information, see MonadMask. class MonadThrow m => MonadCatch (m :: Type -> Type) -- | A class for monads which provide for the ability to account for all -- possible exit points from a computation, and to mask asynchronous -- exceptions. Continuation-based monads are invalid instances of this -- class. -- -- Instances should ensure that, in the following code: -- --
-- fg = f `finally` g ---- -- The action g is called regardless of what occurs within -- f, including async exceptions. Some monads allow f -- to abort the computation via other effects than throwing an exception. -- For simplicity, we will consider aborting and throwing an exception to -- be two forms of "throwing an error". -- -- If f and g both throw an error, the error thrown by -- fg depends on which errors we're talking about. In a monad -- transformer stack, the deeper layers override the effects of the inner -- layers; for example, ExceptT e1 (Except e2) a represents a -- value of type Either e2 (Either e1 a), so throwing both an -- e1 and an e2 will result in Left e2. If -- f and g both throw an error from the same layer, -- instances should ensure that the error from g wins. -- -- Effects other than throwing an error are also overriden by the deeper -- layers. For example, StateT s Maybe a represents a value of -- type s -> Maybe (a, s), so if an error thrown from -- f causes this function to return Nothing, any -- changes to the state which f also performed will be erased. -- As a result, g will see the state as it was before -- f. Once g completes, f's error will be -- rethrown, so g' state changes will be erased as well. This is -- the normal interaction between effects in a monad transformer stack. -- -- By contrast, lifted-base's version of finally always -- discards all of g's non-IO effects, and g never sees -- any of f's non-IO effects, regardless of the layer ordering -- and regardless of whether f throws an error. This is not the -- result of interacting effects, but a consequence of -- MonadBaseControl's approach. class MonadCatch m => MonadMask (m :: Type -> Type) -- | Runs an action with asynchronous exceptions disabled. The action is -- provided a method for restoring the async. environment to what it was -- at the mask call. See Control.Exception's mask. mask :: MonadMask m => ((forall a. () => m a -> m a) -> m b) -> m b -- | Like mask, but the masked computation is not interruptible (see -- Control.Exception's uninterruptibleMask. WARNING: Only -- use if you need to mask exceptions around an interruptible operation -- AND you can guarantee the interruptible operation will only block for -- a short period of time. Otherwise you render the program/thread -- unresponsive and/or unkillable. uninterruptibleMask :: MonadMask m => ((forall a. () => m a -> m a) -> m b) -> m b -- | A generalized version of bracket which uses ExitCase to -- distinguish the different exit cases, and returns the values of both -- the use and release actions. In practice, this extra -- information is rarely needed, so it is often more convenient to use -- one of the simpler functions which are defined in terms of this one, -- such as bracket, finally, onError, and -- bracketOnError. -- -- This function exists because in order to thread their effects through -- the execution of bracket, monad transformers need values to be -- threaded from use to release and from -- release to the output value. -- -- NOTE This method was added in version 0.9.0 of this library. -- Previously, implementation of functions like bracket and -- finally in this module were based on the mask and -- uninterruptibleMask functions only, disallowing some classes of -- tranformers from having MonadMask instances (notably -- multi-exit-point transformers like ExceptT). If you are a -- library author, you'll now need to provide an implementation for this -- method. The StateT implementation demonstrates most of the -- subtleties: -- --
-- generalBracket acquire release use = StateT $ s0 -> do -- ((b, _s2), (c, s3)) <- generalBracket -- (runStateT acquire s0) -- ((resource, s1) exitCase -> case exitCase of -- ExitCaseSuccess (b, s2) -> runStateT (release resource (ExitCaseSuccess b)) s2 -- -- -- In the two other cases, the base monad overrides use's state -- -- changes and the state reverts to s1. -- ExitCaseException e -> runStateT (release resource (ExitCaseException e)) s1 -- ExitCaseAbort -> runStateT (release resource ExitCaseAbort) s1 -- ) -- ((resource, s1) -> runStateT (use resource) s1) -- return ((b, c), s3) ---- -- The StateT s m implementation of generalBracket -- delegates to the m implementation of generalBracket. -- The acquire, use, and release arguments -- given to StateT's implementation produce actions of type -- StateT s m a, StateT s m b, and StateT s m -- c. In order to run those actions in the base monad, we need to -- call runStateT, from which we obtain actions of type m -- (a, s), m (b, s), and m (c, s). Since each -- action produces the next state, it is important to feed the state -- produced by the previous action to the next action. -- -- In the ExitCaseSuccess case, the state starts at s0, -- flows through acquire to become s1, flows through -- use to become s2, and finally flows through -- release to become s3. In the other two cases, -- release does not receive the value s2, so its action -- cannot see the state changes performed by use. This is fine, -- because in those two cases, an error was thrown in the base monad, so -- as per the usual interaction between effects in a monad transformer -- stack, those state changes get reverted. So we start from s1 -- instead. -- -- Finally, the m implementation of generalBracket -- returns the pairs (b, s) and (c, s). For monad -- transformers other than StateT, this will be some other type -- representing the effects and values performed and returned by the -- use and release actions. The effect part of the -- use result, in this case _s2, usually needs to be -- discarded, since those effects have already been incorporated in the -- release action. -- -- The only effect which is intentionally not incorporated in the -- release action is the effect of throwing an error. In that -- case, the error must be re-thrown. One subtlety which is easy to miss -- is that in the case in which use and release both -- throw an error, the error from release should take priority. -- Here is an implementation for ExceptT which demonstrates how -- to do this. -- --
-- generalBracket acquire release use = ExceptT $ do -- (eb, ec) <- generalBracket -- (runExceptT acquire) -- (eresource exitCase -> case eresource of -- Left e -> return (Left e) -- nothing to release, acquire didn't succeed -- Right resource -> case exitCase of -- ExitCaseSuccess (Right b) -> runExceptT (release resource (ExitCaseSuccess b)) -- ExitCaseException e -> runExceptT (release resource (ExitCaseException e)) -- _ -> runExceptT (release resource ExitCaseAbort)) -- (either (return . Left) (runExceptT . use)) -- return $ do -- -- The order in which we perform those two Either effects determines -- -- which error will win if they are both Lefts. We want the error from -- -- release to win. -- c <- ec -- b <- eb -- return (b, c) --generalBracket :: MonadMask m => m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c) -- | O(n) Convert a lazy Text into a strict Text. toStrict :: Text -> Text -- | A set of values. A set cannot contain duplicate values. data HashSet a -- | A state transformer monad parameterized by: -- --
-- instance StoreHasSubmap Store X Key Value where -- storeSubmapOps = storeSubmapOpsReferTo #Y storeSubmapOpsForY --storeSubmapOpsReferTo :: forall (name :: Symbol) storage key value (desiredName :: Symbol). Label name -> StoreSubmapOps storage name key value -> StoreSubmapOps storage desiredName key value -- | Implementation of StoreHasEntrypoint for a data type which has -- an instance of StoreHasEntrypoint inside. For instance, it can -- be used for top-level storage. storeEntrypointOpsDeeper :: forall store (nameInStore :: Symbol) substore (epName :: Symbol) epParam epStore. (HasFieldOfType store nameInStore substore, StoreHasEntrypoint substore epName epParam epStore) => Label nameInStore -> StoreEntrypointOps store epName epParam epStore -- | Implementation of StoreHasSubmap for a data type which has an -- instance of StoreHasSubmap inside. For instance, it can be used -- for top-level storage. storeSubmapOpsDeeper :: forall storage (bigMapPartName :: Symbol) fields (mname :: Symbol) key value. (HasFieldOfType storage bigMapPartName fields, StoreHasSubmap fields mname key value) => Label bigMapPartName -> StoreSubmapOps storage mname key value -- | Implementation of StoreHasField for a data type which has an -- instance of StoreHasField inside. For instance, it can be used -- for top-level storage. storeFieldOpsDeeper :: forall storage (fieldsPartName :: Symbol) fields (fname :: Symbol) ftype. (HasFieldOfType storage fieldsPartName fields, StoreHasField fields fname ftype) => Label fieldsPartName -> StoreFieldOps storage fname ftype -- | Implementation of StoreHasEntrypoint for a datatype that has a -- StoreHasSubmap that contains the entrypoint and a -- StoreHasField for the field such entrypoint operates on. storeEntrypointOpsSubmapField :: forall store (epmName :: Symbol) epParam epStore (epsName :: Symbol) (epName :: Symbol). (StoreHasSubmap store epmName MText (EntrypointLambda epParam epStore), StoreHasField store epsName epStore, KnownValue epParam, KnownValue epStore) => Label epmName -> Label epsName -> StoreEntrypointOps store epName epParam epStore -- | Implementation of StoreHasEntrypoint for a datatype that has a -- StoreHasField for an EntrypointsField that contains the -- entrypoint and a StoreHasField for the field such entrypoint -- operates on. storeEntrypointOpsFields :: forall store (epmName :: Symbol) epParam epStore (epsName :: Symbol) (epName :: Symbol). (StoreHasField store epmName (EntrypointsField epParam epStore), StoreHasField store epsName epStore, KnownValue epParam, KnownValue epStore) => Label epmName -> Label epsName -> StoreEntrypointOps store epName epParam epStore -- | Implementation of StoreHasEntrypoint for a datatype keeping a -- pack of fields, among which one has contains the entrypoint and -- another is what such entrypoint operates on. storeEntrypointOpsADT :: forall store (epmName :: Symbol) epParam epStore (epsName :: Symbol) (epName :: Symbol). (HasFieldOfType store epmName (EntrypointsField epParam epStore), HasFieldOfType store epsName epStore, KnownValue epParam, KnownValue epStore) => Label epmName -> Label epsName -> StoreEntrypointOps store epName epParam epStore -- | Implementation of StoreHasField for case of datatype keeping a -- pack of fields. storeFieldOpsADT :: forall dt (fname :: Symbol) ftype. HasFieldOfType dt fname ftype => StoreFieldOps dt fname ftype -- | Update the sub-storage that the entrypoint operates on. stSetEpStore :: forall store (epName :: Symbol) epParam epStore (s :: [Type]). StoreHasEntrypoint store epName epParam epStore => Label epName -> (epStore : (store : s)) :-> (store : s) -- | Get the sub-storage that the entrypoint operates on, preserving the -- storage itself on the stack. stGetEpStore :: forall store (epName :: Symbol) epParam epStore (s :: [Type]). StoreHasEntrypoint store epName epParam epStore => Label epName -> (store : s) :-> (epStore : (store : s)) -- | Pick the sub-storage that the entrypoint operates on. stToEpStore :: forall store (epName :: Symbol) epParam epStore (s :: [Type]). StoreHasEntrypoint store epName epParam epStore => Label epName -> (store : s) :-> (epStore : s) -- | Stores the entrypoint lambda in the storage. Fails if already set. stSetEpLambda :: forall store (epName :: Symbol) epParam epStore (s :: [Type]). StoreHasEntrypoint store epName epParam epStore => Label epName -> (EntrypointLambda epParam epStore : (store : s)) :-> (store : s) -- | Get stored entrypoint lambda, preserving the storage itself on the -- stack. stGetEpLambda :: forall store (epName :: Symbol) epParam epStore (s :: [Type]). StoreHasEntrypoint store epName epParam epStore => Label epName -> (store : s) :-> (EntrypointLambda epParam epStore : (store : s)) -- | Pick stored entrypoint lambda. stToEpLambda :: forall store (epName :: Symbol) epParam epStore (s :: [Type]). StoreHasEntrypoint store epName epParam epStore => Label epName -> (store : s) :-> (EntrypointLambda epParam epStore : s) -- | Extracts and executes the epName entrypoint lambda from -- storage, returing the updated full storage (store) and the -- produced Operations. stEntrypoint :: forall store (epName :: Symbol) epParam epStore (s :: [Type]). StoreHasEntrypoint store epName epParam epStore => Label epName -> (epParam : (store : s)) :-> (([Operation], store) : s) -- | Update storage field. stSetField :: forall store (fname :: Symbol) ftype (s :: [Type]). StoreHasField store fname ftype => Label fname -> (ftype : (store : s)) :-> (store : s) -- | Get storage field, preserving the storage itself on stack. stGetField :: forall store (fname :: Symbol) ftype (s :: [Type]). StoreHasField store fname ftype => Label fname -> (store : s) :-> (ftype : (store : s)) -- | Pick storage field. stToField :: forall store (fname :: Symbol) ftype (s :: [Type]). StoreHasField store fname ftype => Label fname -> (store : s) :-> (ftype : s) -- | Datatype containing the full implementation of StoreHasField -- typeclass. -- -- We use this grouping because in most cases the implementation will be -- chosen among the default ones, and initializing all methods at once is -- simpler and more consistent. (One can say that we are trying to -- emulate the DerivingVia extension.) data StoreFieldOps store (fname :: Symbol) ftype StoreFieldOps :: (forall (s :: [Type]). () => Label fname -> (store : s) :-> (ftype : s)) -> (forall (s :: [Type]). () => Label fname -> (ftype : (store : s)) :-> (store : s)) -> StoreFieldOps store (fname :: Symbol) ftype [sopToField] :: StoreFieldOps store (fname :: Symbol) ftype -> forall (s :: [Type]). () => Label fname -> (store : s) :-> (ftype : s) [sopSetField] :: StoreFieldOps store (fname :: Symbol) ftype -> forall (s :: [Type]). () => Label fname -> (ftype : (store : s)) :-> (store : s) -- | Provides operations on fields for storage. class StoreHasField store (fname :: Symbol) ftype | store fname -> ftype storeFieldOps :: StoreHasField store fname ftype => StoreFieldOps store fname ftype -- | Datatype containing the full implementation of StoreHasSubmap -- typeclass. -- -- We use this grouping because in most cases the implementation will be -- chosen among the default ones, and initializing all methods at once is -- simpler and more consistent. (One can say that we are trying to -- emulate the DerivingVia extension.) data StoreSubmapOps store (mname :: Symbol) key value StoreSubmapOps :: (forall (s :: [Type]). () => Label mname -> (key : (store : s)) :-> (Bool : s)) -> (forall (s :: [Type]). KnownValue value => Label mname -> (key : (store : s)) :-> (Maybe value : s)) -> (forall (s :: [Type]). () => Label mname -> (key : (Maybe value : (store : s))) :-> (store : s)) -> (forall (s :: [Type]). () => Label mname -> (key : (store : s)) :-> (store : s)) -> (forall (s :: [Type]). () => Label mname -> (key : (value : (store : s))) :-> (store : s)) -> StoreSubmapOps store (mname :: Symbol) key value [sopMem] :: StoreSubmapOps store (mname :: Symbol) key value -> forall (s :: [Type]). () => Label mname -> (key : (store : s)) :-> (Bool : s) [sopGet] :: StoreSubmapOps store (mname :: Symbol) key value -> forall (s :: [Type]). KnownValue value => Label mname -> (key : (store : s)) :-> (Maybe value : s) [sopUpdate] :: StoreSubmapOps store (mname :: Symbol) key value -> forall (s :: [Type]). () => Label mname -> (key : (Maybe value : (store : s))) :-> (store : s) [sopDelete] :: StoreSubmapOps store (mname :: Symbol) key value -> forall (s :: [Type]). () => Label mname -> (key : (store : s)) :-> (store : s) [sopInsert] :: StoreSubmapOps store (mname :: Symbol) key value -> forall (s :: [Type]). () => Label mname -> (key : (value : (store : s))) :-> (store : s) -- | Provides operations on submaps of storage. class StoreHasSubmap store (mname :: Symbol) key value | store mname -> key value storeSubmapOps :: StoreHasSubmap store mname key value => StoreSubmapOps store mname key value -- | Type synonym for a Lambda that can be used as an entrypoint type EntrypointLambda param store = Lambda (param, store) ([Operation], store) -- | Type synonym of a BigMap mapping MText (entrypoint -- names) to EntrypointLambda. -- -- This is useful when defining instances of StoreHasEntrypoint as -- a storage field containing one or more entrypoints (lambdas) of the -- same type. type EntrypointsField param store = BigMap MText EntrypointLambda param store -- | Datatype containing the full implementation of -- StoreHasEntrypoint typeclass. -- -- We use this grouping because in most cases the implementation will be -- chosen among the default ones, and initializing all methods at once is -- simpler and more consistent. (One can say that we are trying to -- emulate the DerivingVia extension.) data StoreEntrypointOps store (epName :: Symbol) epParam epStore StoreEntrypointOps :: (forall (s :: [Type]). () => Label epName -> (store : s) :-> (EntrypointLambda epParam epStore : s)) -> (forall (s :: [Type]). () => Label epName -> (EntrypointLambda epParam epStore : (store : s)) :-> (store : s)) -> (forall (s :: [Type]). () => Label epName -> (store : s) :-> (epStore : s)) -> (forall (s :: [Type]). () => Label epName -> (epStore : (store : s)) :-> (store : s)) -> StoreEntrypointOps store (epName :: Symbol) epParam epStore [sopToEpLambda] :: StoreEntrypointOps store (epName :: Symbol) epParam epStore -> forall (s :: [Type]). () => Label epName -> (store : s) :-> (EntrypointLambda epParam epStore : s) [sopSetEpLambda] :: StoreEntrypointOps store (epName :: Symbol) epParam epStore -> forall (s :: [Type]). () => Label epName -> (EntrypointLambda epParam epStore : (store : s)) :-> (store : s) [sopToEpStore] :: StoreEntrypointOps store (epName :: Symbol) epParam epStore -> forall (s :: [Type]). () => Label epName -> (store : s) :-> (epStore : s) [sopSetEpStore] :: StoreEntrypointOps store (epName :: Symbol) epParam epStore -> forall (s :: [Type]). () => Label epName -> (epStore : (store : s)) :-> (store : s) -- | Provides operations on stored entrypoints. -- -- store is the storage containing both the entrypoint -- epName (note: it has to be in a BigMap to take -- advantage of lazy evaluation) and the epStore field this -- operates on. class StoreHasEntrypoint store (epName :: Symbol) epParam epStore | store epName -> epParam epStore storeEpOps :: StoreHasEntrypoint store epName epParam epStore => StoreEntrypointOps store epName epParam epStore -- | Indicates a submap with given key and value types. data (k2 :: k) ~> (v :: k1) infix 9 ~> -- | Indicates a stored entrypoint with the given param and -- store types. data (param :: k) ::-> (store :: k1) infix 9 ::-> -- | Concise way to write down constraints with expected content of a -- storage. -- -- Use it like follows: -- --
-- type StorageConstraint store = StorageContains store -- [ "fieldInt" := Int -- , "fieldNat" := Nat -- , "epsToNat" := Int ::-> Nat -- , "balances" := Address ~> Int -- ] --type family StorageContains store (content :: [NamedField]) -- | Unwrap a constructor with the given name. Useful for sum types. unwrapUnsafe_ :: forall dt (name :: Symbol) (st :: [Type]). InstrUnwrapC dt name => Label name -> (dt : st) :-> (CtorOnlyField name dt : st) -- | Wrap entry in single-field constructor. Useful for sum types. wrapOne :: forall dt (name :: Symbol) (st :: [Type]). InstrWrapOneC dt name => Label name -> (CtorOnlyField name dt : st) :-> (dt : st) -- | Wrap entry in constructor. Useful for sum types. wrap_ :: forall dt (name :: Symbol) (st :: [Type]). InstrWrapC dt name => Label name -> AppendCtorField (GetCtorField dt name) st :-> (dt : st) -- | Lift an instruction to field constructor. fieldCtor :: forall (st :: [Type]) f. HasCallStack => (st :-> (f : st)) -> FieldConstructor st f -- | Decompose a complex object into its fields deconstruct :: forall dt (fields :: [Type]) (st :: [Type]). (InstrDeconstructC dt, KnownList fields, ToTs fields ~ ToTs (ConstructorFieldTypes dt)) => (dt : st) :-> (fields ++ st) -- | Construct an object from fields on the stack. constructStack :: forall dt (fields :: [Type]) (st :: [Type]). (InstrConstructC dt, ToTs fields ~ ToTs (ConstructorFieldTypes dt), KnownList fields) => (fields ++ st) :-> (dt : st) -- | Apply given modifier to a datatype field. modifyField :: forall dt (name :: Symbol) (st :: [Type]). (InstrGetFieldC dt name, InstrSetFieldC dt name) => Label name -> (forall (st0 :: [Type]). () => (GetFieldType dt name : st0) :-> (GetFieldType dt name : st0)) -> (dt : st) :-> (dt : st) -- | Like getField, but leaves field named. getFieldNamed :: forall dt (name :: Symbol) (st :: [Type]). InstrGetFieldC dt name => Label name -> (dt : st) :-> ((name :! GetFieldType dt name) : (dt : st)) -- | Extract a field of a datatype, leaving the original datatype on stack. getField :: forall dt (name :: Symbol) (st :: [Type]). InstrGetFieldC dt name => Label name -> (dt : st) :-> (GetFieldType dt name : (dt : st)) -- | Like toField, but leaves field named. toFieldNamed :: forall dt (name :: Symbol) (st :: [Type]). InstrGetFieldC dt name => Label name -> (dt : st) :-> ((name :! GetFieldType dt name) : st) -- | Extract a field of a datatype replacing the value of this datatype -- with the extracted field. -- -- For this and the following functions you have to specify field name -- which is either record name or name attached with (:!) -- operator. toField :: forall dt (name :: Symbol) (st :: [Type]). InstrGetFieldC dt name => Label name -> (dt : st) :-> (GetFieldType dt name : st) -- | Like HasField, but allows constrainting field type. type HasFieldOfType dt (fname :: Symbol) fieldTy = (HasField dt fname, GetFieldType dt fname ~ fieldTy) -- | A pair of field name and type. data NamedField NamedField :: Symbol -> Type -> NamedField type (n :: Symbol) := ty = 'NamedField n ty infixr 0 := -- | Shortcut for multiple HasFieldOfType constraints. type family HasFieldsOfType dt (fs :: [NamedField]) -- | Lorentz analogy of CaseClause, it works on plain Type -- types. data CaseClauseL (inp :: [Type]) (out :: [Type]) (param :: CaseClauseParam) [CaseClauseL] :: forall (x :: CtorField) (inp :: [Type]) (out :: [Type]) (ctor :: Symbol). (AppendCtorField x inp :-> out) -> CaseClauseL inp out ('CaseClauseParam ctor x) -- | Provides "case" arrow which works on different wrappers for clauses. class CaseArrow (name :: Symbol) body clause | clause -> name, clause -> body -- | Lift an instruction to case clause. -- -- You should write out constructor name corresponding to the clause -- explicitly. Prefix constructor name with "c" letter, otherwise your -- label will not be recognized by Haskell parser. Passing constructor -- name can be circumvented but doing so is not recomended as mentioning -- contructor name improves readability and allows avoiding some -- mistakes. (/->) :: CaseArrow name body clause => Label name -> body -> clause infixr 0 /-> type CaseTC dt (out :: [Type]) (inp :: [Type]) clauses = (InstrCaseC dt, RMap CaseClauses dt, RecFromTuple clauses, clauses ~ Rec CaseClauseL inp out CaseClauses dt) -- | Handlers for most common errors defined in Lorentz. baseErrorDocHandlers :: [NumericErrorDocHandler] -- | Handler for VoidResult. voidResultDocHandler :: NumericErrorDocHandler -- | Handler for all CustomErrors. customErrorDocHandler :: NumericErrorDocHandler -- | Extended version of applyErrorTagToErrorsDoc which accepts -- error handlers. -- -- In most cases that function should be enough for your purposes, but it -- uses a fixed set of base handlers which may be not enough in case when -- you define your own errors. In this case define and pass all the -- necessary handlers to this function. -- -- It fails with error if some of the errors used in the contract -- cannot be handled with given handlers. applyErrorTagToErrorsDocWith :: forall (inp :: [Type]) (out :: [Type]). HasCallStack => [NumericErrorDocHandler] -> ErrorTagMap -> (inp :-> out) -> inp :-> out -- | Modify documentation generated for given code so that all -- CustomError mention not their textual error tag rather -- respective numeric one from the given map. -- -- If some documented error is not present in the map, it remains -- unmodified. This function may fail with error if contract uses -- some uncommon errors, see applyErrorTagToErrorsDocWith for -- details. applyErrorTagToErrorsDoc :: forall (inp :: [Type]) (out :: [Type]). HasCallStack => ErrorTagMap -> (inp :-> out) -> inp :-> out -- | Adds a section which explains error tag mapping. data DDescribeErrorTagMap DDescribeErrorTagMap :: Text -> DDescribeErrorTagMap -- | Describes where the error tag map is defined in Haskell code. [detmSrcLoc] :: DDescribeErrorTagMap -> Text -- | Errors for NumericErrorDocHandler data NumericErrorDocHandlerError -- | Handler which changes documentation for one particular error type. data NumericErrorDocHandler -- | Some error with a numeric tag attached. data NumericErrorWrapper (numTag :: Nat) err voidResultTag :: MText -- | view type synonym as described in A1. data View a r -- | void type synonym as described in A1. data Void_ a b -- | Newtype over void result type used in tests to distinguish successful -- void result from other errors. -- -- Usage example: lExpectFailWith (== VoidResult roleMaster)` -- -- This error is special - it can contain arguments of different types -- depending on entrypoint which raises it. data VoidResult r -- | Implementation of castDummy for types composed from smaller -- types. It helps to ensure that all necessary constraints are requested -- in instance head. castDummyG :: (Generic a, Generic b, GCanCastTo (Rep a) (Rep b)) => Proxy a -> Proxy b -> () -- | Locally provide bidirectional CanCastTo instance. allowCheckedCoerce :: forall k1 k2 (a :: k1) (b :: k2). Dict (CanCastTo a b, CanCastTo b a) -- | Locally provide given CanCastTo instance. allowCheckedCoerceTo :: forall k1 k2 (b :: k1) (a :: k2). Dict (CanCastTo a b) -- | Pretends that the top item of the stack was coerced. checkedCoercing_ :: forall a b (s :: [Type]). Coercible_ a b => ((b : s) :-> (b : s)) -> (a : s) :-> (a : s) -- | Coerce between types which have an explicit permission for that in the -- face of CanCastTo constraint. checkedCoerce_ :: forall a b (s :: [Type]). Castable_ a b => (a : s) :-> (b : s) -- | Coercion in Haskell world which respects CanCastTo. checkedCoerce :: (CanCastTo a b, Coercible a b) => a -> b -- | Unpack named value. fromNamed :: forall (name :: Symbol) a (s :: [Type]). Label name -> (NamedF Identity a name : s) :-> (a : s) -- | Lift given value to a named value. toNamed :: forall (name :: Symbol) a (s :: [Type]). Label name -> (a : s) :-> (NamedF Identity a name : s) -- | Specialized version of coerce_ to unwrap a haskell newtype. coerceUnwrap :: forall a (s :: [Type]). Wrappable a => (a : s) :-> (Unwrappable a : s) -- | Specialized version of coerce_ to wrap into a haskell -- newtype. coerceWrap :: forall a (s :: [Type]). Wrappable a => (Unwrappable a : s) :-> (a : s) fakeCoercing :: forall (s1 :: [Type]) (s2 :: [Type]) (s1' :: [Type]) (s2' :: [Type]). (s1 :-> s2) -> s1' :-> s2' -- | Convert between two stacks via failing. fakeCoerce :: forall (s1 :: [Type]) (s2 :: [Type]). s1 :-> s2 gForcedCoerce_ :: forall k t (a :: k) (b :: k) (s :: [Type]). MichelsonCoercible (t a) (t b) => (t a : s) :-> (t b : s) -- | Convert between values of types that have the same representation. -- -- This function is not safe in a sense that this allows * breaking -- invariants of casted type (example: UStore from -- morley-upgradeable), or * may stop compile on code changes (example: -- coercion of pair to a datatype with two fields will break if new field -- is added). Still, produced Michelson code will always be valid. -- -- Prefer using one of more specific functions from this module. forcedCoerce_ :: forall a b (s :: [Type]). MichelsonCoercible a b => (a : s) :-> (b : s) -- | Whether two types have the same Michelson representation. type MichelsonCoercible a b = ToT a ~ ToT b -- | Explicitly allowed coercions. -- -- a CanCastTo b proclaims that a can be casted -- to b without violating any invariants of b. -- -- This relation is reflexive; it may be symmetric or not. It -- tends to be composable: casting complex types usually requires -- permission to cast their respective parts; for such types consider -- using castDummyG as implementation of the method of this -- typeclass. -- -- For cases when a cast from a to b requires some -- validation, consider rather making a dedicated function which performs -- the necessary checks and then calls forcedCoerce. class CanCastTo (a :: k) (b :: k1) -- | An optional method which helps passing -Wredundant-constraints check. -- Also, you can set specific implementation for it with specific sanity -- checks. castDummy :: CanCastTo a b => Proxy a -> Proxy b -> () -- | Coercion from a to b is permitted and safe. type Castable_ a b = (MichelsonCoercible a b, CanCastTo a b) -- | Coercions between a to b are permitted and safe. type Coercible_ a b = (MichelsonCoercible a b, CanCastTo a b, CanCastTo b a) -- | If you apply numeric error representation in your contract, -- errorToVal will stop working because it doesn't know about this -- transformation. This function takes this transformation into account. -- If a string is used as a tag, but it is not found in the passed map, -- we conservatively preserve that string (because this whole approach is -- rather a heuristic). errorToValNumeric :: IsError e => ErrorTagMap -> e -> (forall (t :: T). ErrorScope t => Value t -> r) -> r -- | If you apply numeric error representation in your contract, -- errorFromVal will stop working because it doesn't know about -- this transformation. This function takes this transformation into -- account. If a number is used as a tag, but it is not found in the -- passed map, we conservatively preserve that number (because this whole -- approach is rather a heuristic). errorFromValNumeric :: forall (t :: T) e. (KnownT t, IsError e) => ErrorTagMap -> Value t -> Either Text e -- | This function implements the simplest scenario of using this module's -- functionality: 1. Gather all error tags from a single instruction. 2. -- Turn them into error conversion map. 3. Apply this conversion. useNumericErrors :: forall (inp :: [Type]) (out :: [Type]). HasCallStack => (inp :-> out) -> (inp :-> out, ErrorTagMap) -- | Similar to applyErrorTagMap, but for case when you have -- excluded some tags from map via excludeErrorTags. Needed, -- because both excludeErrorTags and this function do not tolerate -- unknown errors in contract code (for your safety). applyErrorTagMapWithExclusions :: forall (inp :: [Type]) (out :: [Type]). HasCallStack => ErrorTagMap -> ErrorTagExclusions -> (inp :-> out) -> inp :-> out -- | For each typical FAILWITH that uses a string to represent error -- tag this function changes error tag to be a number using the supplied -- conversion map. It assumes that supplied map contains all such strings -- (and will error out if it does not). It will always be the case if you -- gather all error tags using gatherErrorTags and build -- ErrorTagMap from them using addNewErrorTags. applyErrorTagMap :: forall (inp :: [Type]) (out :: [Type]). HasCallStack => ErrorTagMap -> (inp :-> out) -> inp :-> out -- | Remove some error tags from map. This way you say to remain these -- string tags intact, while others will be converted to numbers when -- this map is applied. -- -- Note that later you have to apply this map using -- applyErrorTagMapWithExclusions, otherwise an error would be -- raised. excludeErrorTags :: HasCallStack => ErrorTagExclusions -> ErrorTagMap -> ErrorTagMap -- | Build ErrorTagMap from a set of textual tags. buildErrorTagMap :: HashSet MText -> ErrorTagMap -- | Add more error tags to an existing ErrorTagMap. It is useful -- when your contract consists of multiple parts (e. g. in case of -- contract upgrade), you have existing map for some part and want to add -- tags from another part to it. You can pass empty map as existing one -- if you just want to build ErrorTagMap from a set of textual -- tags. See buildErrorTagMap. addNewErrorTags :: ErrorTagMap -> HashSet MText -> ErrorTagMap -- | Find all textual error tags that are used in typical FAILWITH -- patterns within given instruction. Map them to natural numbers. gatherErrorTags :: forall (inp :: [Type]) (out :: [Type]). (inp :-> out) -> HashSet MText -- | This is a bidirectional map with correspondence between numeric and -- textual error tags. type ErrorTagMap = Bimap Natural MText -- | Tags excluded from map. type ErrorTagExclusions = HashSet MText -- | QuasiQuote that helps generating TypeHasDoc instance. -- -- Usage: -- --
-- [typeDoc| <type> <description> |] -- [typeDoc| Storage "This is storage description" |] ---- -- See this tutorial which includes this quasiquote. typeDoc :: QuasiQuoter -- | QuasiQuote that helps generating CustomErrorHasDoc instance. -- -- Usage: -- --
-- [errorDoc| <error-name> <error-type> <error-description> |] -- [errorDoc| "errorName" exception "Error description" |] ---- -- See this tutorial which includes this quasiquote. errorDoc :: QuasiQuoter -- | QuasiQuote that helps generating ParameterHasEntrypoints -- instance. -- -- Usage: -- --
-- [entrypointDoc| Parameter <parameter-type> <optional-root-annotation> |] -- [entrypointDoc| Parameter plain |] -- [entrypointDoc| Parameter plain "root"|] ---- -- See this tutorial which includes this quasiquote. entrypointDoc :: QuasiQuoter -- | Implementation of typeDocMdDescription (of TypeHasDoc -- typeclass) for Haskell types which sole purpose is to be error. typeDocMdDescriptionReferToError :: IsError e => Markdown -- | Whether given error class is about internal errors. -- -- Internal errors are not enlisted on per-entrypoint basis, only once -- for the entire contract. isInternalErrorClass :: ErrorClass -> Bool errorTagToText :: forall (tag :: Symbol). KnownSymbol tag => Text -- | Demote error tag to term level. errorTagToMText :: forall (tag :: Symbol). Label tag -> MText -- | Description of error representation in Haskell. customErrorDocHaskellRepGeneral :: forall (tag :: Symbol). (SingI (ToT (ErrorArg tag)), IsError (CustomError tag), TypeHasDoc (ErrorArg tag), CustomErrorHasDoc tag) => Text -> Proxy tag -> Markdown -- | Fail, providing a reference to the place in the code where this -- function is called. -- -- Like error in Haskell code, this instruction is for internal -- errors only. failUnexpected :: forall (s :: [Type]) (t :: [Type]). MText -> s :-> t -- | Fail with the given Haskell value. failUsing :: forall e (s :: [Type]) (t :: [Type]). IsError e => e -> s :-> t -- | Implementation of errorFromVal via IsoValue. isoErrorFromVal :: forall (t :: T) e. (Typeable t, Typeable (ToT e), IsoValue e) => Value t -> Either Text e -- | Implementation of errorToVal via IsoValue. isoErrorToVal :: (KnownError e, IsoValue e) => e -> (forall (t :: T). ErrorScope t => Value t -> r) -> r type ErrorScope (t :: T) = (Typeable t, ConstantScope t) -- | Haskell type representing error. class (Typeable e, ErrorHasDoc e) => IsError e -- | Converts a Haskell error into Value representation. errorToVal :: IsError e => e -> (forall (t :: T). ErrorScope t => Value t -> r) -> r -- | Converts a Value into Haskell error. errorFromVal :: forall (t :: T). (IsError e, KnownT t) => Value t -> Either Text e -- | Constraints which we require in a particular instance. You are not -- oblidged to often instantiate this correctly, it is only useful for -- some utilities. type family ErrorRequirements e class Typeable e => ErrorHasDoc e where { -- | Constraints which we require in a particular instance. You are not -- oblidged to often instantiate this correctly, it is only useful for -- some utilities. type family ErrorRequirements e; type ErrorRequirements e = (); } -- | Name of error as it appears in the corresponding section title. errorDocName :: ErrorHasDoc e => Text -- | What should happen for this error to be raised. errorDocMdCause :: ErrorHasDoc e => Markdown -- | Brief version of errorDocMdCause. -- -- This will appear along with the error when mentioned in entrypoint -- description. By default, the first sentence of the full description is -- used. errorDocMdCauseInEntrypoint :: ErrorHasDoc e => Markdown -- | How this error is represented in Haskell. errorDocHaskellRep :: ErrorHasDoc e => Markdown -- | Error class. errorDocClass :: ErrorHasDoc e => ErrorClass -- | Which definitions documentation for this error mentions. errorDocDependencies :: ErrorHasDoc e => [SomeDocDefinitionItem] -- | Captured constraints which we require in a particular instance. This -- is a way to encode a bidirectional instance in the nowaday Haskell, -- for class MyConstraint => ErrorHasDoc MyType instance it -- lets deducing MyConstraint by ErrorHasDoc MyType. -- -- You are not oblidged to always instantiate, it is only useful for some -- utilities which otherwise would not compile. errorDocRequirements :: ErrorHasDoc e => Dict (ErrorRequirements e) -- | Use this type as replacement for () when you really -- want to leave error cause unspecified. data UnspecifiedError UnspecifiedError :: UnspecifiedError -- | Type wrapper for an IsError. data SomeError SomeError :: e -> SomeError -- | Declares a custom error, defining error name - error argument -- relation. -- -- If your error is supposed to carry no argument, then provide -- (). -- -- Note that this relation is defined globally rather than on -- per-contract basis, so define errors accordingly. If your error has -- argument specific to your contract, call it such that error name -- reflects its belonging to this contract. -- -- This is the basic [error format]. type family ErrorArg (tag :: Symbol) -- | Material custom error. -- -- Use this in pattern matches against error (e.g. in tests). data CustomError (tag :: Symbol) CustomError :: Label tag -> ErrorArg tag -> CustomError (tag :: Symbol) [ceTag] :: CustomError (tag :: Symbol) -> Label tag [ceArg] :: CustomError (tag :: Symbol) -> ErrorArg tag type RequireNoArgError (tag :: Symbol) (msg :: ErrorMessage) = (TypeErrorUnless ErrorArg tag == () msg, msg ~ 'Text "Expected no-arg error, but given error requires argument of type " :<>: 'ShowType ErrorArg tag) -- | Error class on how the error should be handled by the client. data ErrorClass -- | Normal expected error. Examples: "insufficient balance", "wallet does -- not exist". ErrClassActionException :: ErrorClass -- | Invalid argument passed to entrypoint. Examples: your entrypoint -- accepts an enum represented as nat, and unknown value is -- provided. This includes more complex cases which involve multiple -- entrypoints. E.g. API provides iterator interface, middleware should -- care about using it hiding complex details and exposing a simpler API -- to user; then an attempt to request non-existing element would also -- correspond to an error from this class. ErrClassBadArgument :: ErrorClass -- | Unexpected error. Most likely it means that there is a bug in the -- contract or the contract has been deployed incorrectly. ErrClassContractInternal :: ErrorClass -- | It's possible to leave error class unspecified. ErrClassUnknown :: ErrorClass class (KnownSymbol tag, TypeHasDoc ErrorArg tag, IsError CustomError tag) => CustomErrorHasDoc (tag :: Symbol) -- | What should happen for this error to be raised. customErrDocMdCause :: CustomErrorHasDoc tag => Markdown -- | Brief version of customErrDocMdCause. This will appear along -- with the error when mentioned in entrypoint description. -- -- By default, the first sentence of the full description is used. customErrDocMdCauseInEntrypoint :: CustomErrorHasDoc tag => Markdown -- | Error class. -- -- By default this returns "unknown error" class; though you should -- provide explicit implementation in order to avoid a warning. customErrClass :: CustomErrorHasDoc tag => ErrorClass -- | Clarification of error argument meaning. -- -- Provide when it's not obvious, e.g. argument is not named with -- :!. -- -- NOTE: This should not be an entire sentence, rather just the -- semantic backbone. -- -- Bad: * Error argument stands for the previous value of -- approval. -- -- Good: * the previous value of approval * pair, first -- argument of which is one thing, and the second is another customErrArgumentSemantics :: CustomErrorHasDoc tag => Maybe Markdown -- | Mentions that contract uses given error. data DError [DError] :: forall e. ErrorHasDoc e => Proxy e -> DError -- | Documentation for custom errors. -- -- Mentions that entrypoint throws given error. data DThrows [DThrows] :: forall e. ErrorHasDoc e => Proxy e -> DThrows -- | Remove element with the given type from the stack. dropT :: forall a (inp :: [Type]) (dinp :: [Type]) (dout :: [Type]) (out :: [Type]). (DipT inp a inp dinp dout out, dinp ~ (a : dout)) => inp :-> out -- | Dip repeatedly until element of the given type is on top of the stack. -- -- If stack contains multiple entries of this type, compile error is -- raised. dipT :: forall a (inp :: [Type]) (dinp :: [Type]) (dout :: [Type]) (out :: [Type]). DipT inp a inp dinp dout out => (dinp :-> dout) -> inp :-> out -- | Duplicate an element of stack referring it by type. -- -- If stack contains multiple entries of this type, compile error is -- raised. dupT :: forall a (st :: [Type]). DupT st a st => st :-> (a : st) class NonZero t -- | Similar to valueToScriptExpr, but for values encoded as -- Expressions. This is only used in tests. expressionToScriptExpr :: Expression -> ByteString -- | This function transforms Lorentz values into script_expr. -- -- script_expr is used in RPC as an argument in entrypoint -- designed for getting value by key from the big_map in Babylon. In -- order to convert value to the script_expr we have to pack it, -- take blake2b hash and add specific expr prefix. Take a look -- at -- https://gitlab.com/tezos/tezos/blob/6e25ae8eb385d9975a30388c7a7aa2a9a65bf184/src/proto_005_PsBabyM1/lib_protocol/script_expr_hash.ml -- and -- https://gitlab.com/tezos/tezos/blob/6e25ae8eb385d9975a30388c7a7aa2a9a65bf184/src/proto_005_PsBabyM1/lib_protocol/contract_services.ml#L136 -- for more information. valueToScriptExpr :: NicePackedValue t => t -> ByteString lEncodeValue :: NicePrintedValue a => a -> ByteString lUnpackValue :: NiceUnpackedValue a => Packed a -> Either UnpackError a lPackValue :: NicePackedValue a => a -> Packed a lUnpackValueRaw :: NiceUnpackedValue a => ByteString -> Either UnpackError a lPackValueRaw :: NicePackedValue a => a -> ByteString -- | Evaluate hash in Haskell world. toHashHs :: forall (alg :: HashAlgorithmKind) bs. (BytesLike bs, KnownHashAlgorithm alg) => bs -> Hash alg bs -- | Sign data using Ed25519 curve. TODO [#456]: handle other methods, -- either all at once (if viable) or each one separately lSignEd22519 :: BytesLike a => SecretKey -> a -> TSignature a -- | Everything which is represented as bytes inside. class (KnownValue bs, ToT bs ~ ToT ByteString) => BytesLike bs toBytes :: BytesLike bs => bs -> ByteString -- | Represents a ByteString resulting from packing a value of type -- a. -- -- This is not guaranteed to keep some packed value, and -- unpack can fail. We do so because often we need to accept -- values of such type from user, and also because there is no simple way -- to check validity of packed data without performing full unpack. So -- this wrapper is rather a hint for users. newtype Packed a Packed :: ByteString -> Packed a [unPacked] :: Packed a -> ByteString -- | Represents a signature, where signed data has given type. -- -- Since we usually sign a packed data, a common pattern for this type is -- TSignature (Packed signedData). If you don't want to -- use Packed, use plain TSignature ByteString instead. newtype TSignature a TSignature :: Signature -> TSignature a [unTSignature] :: TSignature a -> Signature -- | Hash of type t evaluated from data of type a. newtype Hash (alg :: HashAlgorithmKind) a HashUnsafe :: ByteString -> Hash (alg :: HashAlgorithmKind) a [unHash] :: Hash (alg :: HashAlgorithmKind) a -> ByteString -- | Hash algorithm used in Tezos. class Typeable alg => KnownHashAlgorithm (alg :: HashAlgorithmKind) hashAlgorithmName :: KnownHashAlgorithm alg => Proxy alg -> Text computeHash :: KnownHashAlgorithm alg => ByteString -> ByteString toHash :: forall bs (s :: [Type]). (KnownHashAlgorithm alg, BytesLike bs) => (bs : s) :-> (Hash alg bs : s) -- | Documentation item for hash algorithms. data DHashAlgorithm data Sha256 (a :: HashAlgoTag) data Sha512 (a :: HashAlgoTag) data Blake2b (a :: HashAlgoTag) mkDEntrypointExample :: NiceParameter a => a -> DEntrypointExample -- | Leave only instructions related to documentation. -- -- This function is useful when your method executes a lambda coming from -- outside, but you know its properties and want to propagate its -- documentation to your contract code. cutLorentzNonDoc :: forall (inp :: [Type]) (out :: [Type]) (s :: [Type]). (inp :-> out) -> s :-> s renderLorentzDocWithGitRev :: forall (inp :: [Type]) (out :: [Type]). DGitRevision -> (inp :-> out) -> LText renderLorentzDoc :: forall (inp :: [Type]) (out :: [Type]). (inp :-> out) -> LText buildLorentzDocWithGitRev :: forall (inp :: [Type]) (out :: [Type]). DGitRevision -> (inp :-> out) -> ContractDoc buildLorentzDoc :: forall (inp :: [Type]) (out :: [Type]). (inp :-> out) -> ContractDoc -- | Modify the example value of an entrypoint data DEntrypointExample DEntrypointExample :: Value t -> DEntrypointExample -- | Pretty-print a Lorentz contract into Michelson code. printLorentzContract :: (NiceParameterFull cp, NiceStorage st) => Bool -> Contract cp st -> LText -- | Pretty-print a Haskell value as Michelson one. printLorentzValue :: NicePrintedValue v => Bool -> v -> LText -- | Lorentz version of analyzer. analyzeLorentz :: forall (inp :: [Type]) (out :: [Type]). (inp :-> out) -> AnalyzerRes -- | Like interpretLorentzInstr, but works on lambda rather than -- arbitrary instruction. interpretLorentzLambda :: (IsoValue inp, IsoValue out) => ContractEnv -> Lambda inp out -> inp -> Either MichelsonFailed out -- | Interpret a Lorentz instruction, for test purposes. Note that this -- does not run the optimizer. interpretLorentzInstr :: forall (inp :: [Type]) (out :: [Type]). (IsoValuesStack inp, IsoValuesStack out) => ContractEnv -> (inp :-> out) -> Rec Identity inp -> Either MichelsonFailed (Rec Identity out) -- | Compile a whole contract to Michelson. -- -- Note that compiled contract can be ill-typed in terms of Michelson -- code when some of the compilation options are used (e.g. when -- ccoDisableInitialCast is True, resulted contract can -- be ill-typed). However, compilation with -- defaultContractCompilationOptions should be valid. compileLorentzContract :: (NiceParameterFull cp, NiceStorage st) => Contract cp st -> Contract (ToT cp) (ToT st) -- | Compile contract with defaultCompilationOptions and -- cDisableInitialCast set to False. defaultContract :: ContractCode cp st -> Contract cp st -- | Compile Lorentz code, optionally running the optimizer, string and -- byte transformers. compileLorentzWithOptions :: forall (inp :: [Type]) (out :: [Type]). CompilationOptions -> (inp :-> out) -> Instr (ToTs inp) (ToTs out) -- | For use outside of Lorentz. Will use defaultCompilationOptions. compileLorentz :: forall (inp :: [Type]) (out :: [Type]). (inp :-> out) -> Instr (ToTs inp) (ToTs out) -- | Runs Michelson optimizer with default config and does not touch -- strings and bytes. defaultCompilationOptions :: CompilationOptions -- | Options to control Lorentz to Michelson compilation. data CompilationOptions CompilationOptions :: Maybe OptimizerConf -> (Bool, MText -> MText) -> (Bool, ByteString -> ByteString) -> CompilationOptions -- | Config for Michelson optimizer. [coOptimizerConf] :: CompilationOptions -> Maybe OptimizerConf -- | Function to transform strings with. See -- transformStringsLorentz. [coStringTransformer] :: CompilationOptions -> (Bool, MText -> MText) -- | Function to transform byte strings with. See -- transformBytesLorentz. [coBytesTransformer] :: CompilationOptions -> (Bool, ByteString -> ByteString) -- | Wrap parameter into this to locally assign a way to derive entrypoints -- for it. newtype ParameterWrapper deriv cp ParameterWrapper :: cp -> ParameterWrapper deriv cp [unParameterWraper] :: ParameterWrapper deriv cp -> cp type family Unwrappable s -- | Wrappable is similar to lens Wrapped class without the -- method. It provides type family that is mainly used as constraint when -- unwrapping Lorentz instruction into a Haskell newtype and vice versa. class ToT s ~ ToT Unwrappable s => Wrappable s where { type family Unwrappable s; type Unwrappable s = GUnwrappable Rep s; } type family ArithResHs aop n m -- | Lifted ArithOp. class (ArithOp aop ToT n ToT m, NiceComparable n, NiceComparable m, ToT ArithResHs aop n m ~ ArithRes aop ToT n ToT m) => ArithOpHs aop n m where { type family ArithResHs aop n m; } type family UnaryArithResHs aop n -- | Lifted UnaryArithOp. class (UnaryArithOp aop ToT n, NiceComparable n, ToT UnaryArithResHs aop n ~ UnaryArithRes aop ToT n) => UnaryArithOpHs aop n where { type family UnaryArithResHs aop n; } -- | Implementation of ParameterHasEntrypoints which fits for case -- when your contract exposes multiple entrypoints via having sum type as -- its parameter. -- -- In particular, each constructor would produce a homonymous entrypoint -- with argument type equal to type of constructor field (each -- constructor should have only one field). Constructor called -- Default will designate the default entrypoint. data EpdPlain -- | Extension of EpdPlain on parameters being defined as several -- nested datatypes. -- -- In particular, this will traverse sum types recursively, stopping at -- Michelson primitives (like Natural) and constructors with -- number of fields different from one. -- -- It does not assign names to intermediate nodes of Or tree, only -- to the very leaves. -- -- If some entrypoint arguments have custom IsoValue instance, -- this derivation way will not work. As a workaround, you can wrap your -- argument into some primitive (e.g. :!). data EpdRecursive -- | Extension of EpdPlain on parameters being defined as several -- nested datatypes. -- -- In particular, it will traverse the immediate sum type, and require -- another ParameterHasEntrypoints for the inner complex -- datatypes. Only those inner types are considered which are the only -- fields in their respective constructors. Inner types should not -- themselves declare default entrypoint, we enforce this for better -- modularity. Each top-level constructor will be treated as entrypoint -- even if it contains a complex datatype within, in such case that would -- be an entrypoint corresponding to intermediate node in or -- tree. -- -- Comparing to EpdRecursive this gives you more control over -- where and how entrypoints will be derived. data EpdDelegate -- | Extension of EpdPlain, EpdRecursive, and -- EpdDelegate which allow specifying root annotation for the -- parameters. data EpdWithRoot (r :: Symbol) (epd :: k) type List = [] -- | Provides Buildable instance that prints Lorentz value via -- Michelson's Value. -- -- Result won't be very pretty, but this avoids requiring Show or -- Buildable instances. newtype PrintAsValue a PrintAsValue :: a -> PrintAsValue a type family MemOpKeyHs c -- | Lifted MemOpKey. class (MemOp ToT c, ToT MemOpKeyHs c ~ MemOpKey ToT c) => MemOpHs c where { type family MemOpKeyHs c; } -- | A useful property which holds for reasonable MapOp instances. -- -- It's a separate thing from MapOpHs because it mentions -- b type parameter. type family IsoMapOpRes c b type family MapOpResHs c :: Type -> Type type family MapOpInpHs c -- | Lifted MapOp. class (MapOp ToT c, ToT MapOpInpHs c ~ MapOpInp ToT c, ToT MapOpResHs c () ~ MapOpRes ToT c ToT ()) => MapOpHs c where { type family MapOpInpHs c; type family MapOpResHs c :: Type -> Type; } type family IterOpElHs c -- | Lifted IterOp. class (IterOp ToT c, ToT IterOpElHs c ~ IterOpEl ToT c) => IterOpHs c where { type family IterOpElHs c; } -- | Lifted SizeOp. -- -- This could be just a constraint alias, but to avoid T types -- appearance in error messages we make a full type class with concrete -- instances. class SizeOp ToT c => SizeOpHs c type family UpdOpParamsHs c type family UpdOpKeyHs c -- | Lifted UpdOp. class (UpdOp ToT c, ToT UpdOpKeyHs c ~ UpdOpKey ToT c, ToT UpdOpParamsHs c ~ UpdOpParams ToT c) => UpdOpHs c where { type family UpdOpKeyHs c; type family UpdOpParamsHs c; } type family GetOpValHs c type family GetOpKeyHs c -- | Lifted GetOp. class (GetOp ToT c, ToT GetOpKeyHs c ~ GetOpKey ToT c, ToT GetOpValHs c ~ GetOpVal ToT c) => GetOpHs c where { type family GetOpKeyHs c; type family GetOpValHs c; } -- | Lifted ConcatOp. class ConcatOp ToT c => ConcatOpHs c -- | Lifted SliceOp. class SliceOp ToT c => SliceOpHs c type family EModOpResHs n m type family EDivOpResHs n m -- | Lifted EDivOp. class (EDivOp ToT n ToT m, NiceComparable n, NiceComparable m, ToT EDivOpResHs n m ~ EDivOpRes ToT n ToT m, ToT EModOpResHs n m ~ EModOpRes ToT n ToT m) => EDivOpHs n m where { type family EDivOpResHs n m; type family EModOpResHs n m; } -- | Fix the current type of the stack to be given one. -- --
-- >>> stackType @'[Natural] -- -- >>> stackType @(Integer : Natural : s) -- -- >>> stackType @'["balance" :! Integer, "toSpend" :! Integer, BigMap Address Integer] ---- -- Note that you can omit arbitrary parts of the type. -- --
-- >>> stackType @'["balance" :! Integer, "toSpend" :! _, BigMap _ _] --stackType :: forall (s :: [Type]). s :-> s -- | Test an invariant, fail if it does not hold. -- -- This won't be included into production contract and is executed only -- in tests. testAssert :: forall (out :: [Type]) (inp :: [Type]). (Typeable (ToTs out), HasCallStack) => Text -> PrintComment (ToTs inp) -> (inp :-> (Bool : out)) -> inp :-> inp -- | Print a comment. It will be visible in tests. -- --
-- >>> printComment "Hello world!" -- -- >>> printComment $ "On top of the stack I see " <> stackRef @0 --printComment :: forall (s :: [Type]). PrintComment (ToTs s) -> s :-> s -- | Include a value at given position on stack into comment produced by -- printComment. -- --
-- >>> stackRef @0 -- <includes the top of the stack> --stackRef :: forall (gn :: Nat) (st :: [T]) (n :: Peano). (n ~ ToPeano gn, SingI n, KnownPeano n, RequireLongerThan st n) => PrintComment st convertContractRef :: forall cp contract2 contract1. (ToContractRef cp contract1, FromContractRef cp contract2) => contract1 -> contract2 -- | Specification of callTAddress to call the default entrypoint. callingDefTAddress :: NiceParameterFull cp => TAddress cp -> ContractRef (GetDefaultEntrypointArg cp) -- | Turn TAddress to ContractRef in Haskell world. -- -- This is an analogy of address to contract convertion -- in Michelson world, thus you have to supply an entrypoint (or call the -- default one explicitly). callingTAddress :: forall cp (mname :: Maybe Symbol). NiceParameterFull cp => TAddress cp -> EntrypointRef mname -> ContractRef (GetEntrypointArgCustom cp mname) -- | Address which remembers the parameter type of the contract it refers -- to. -- -- It differs from Michelson's contract type because it cannot -- contain entrypoint, and it always refers to entire contract parameter -- even if this contract has explicit default entrypoint. newtype TAddress (p :: k) TAddress :: Address -> TAddress (p :: k) [unTAddress] :: TAddress (p :: k) -> Address -- | Address associated with value of contract arg type. -- -- Places where ContractRef can appear are now severely limited, -- this type gives you type-safety of ContractRef but still can be -- used everywhere. This type is not a full-featured one rather a helper; -- in particular, once pushing it on stack, you cannot return it back to -- Haskell world. -- -- Note that it refers to an entrypoint of the contract, not just the -- contract as a whole. In this sense this type differs from -- TAddress. -- -- Unlike with ContractRef, having this type you still cannot be -- sure that the referred contract exists and need to perform a lookup -- before calling it. newtype FutureContract arg FutureContract :: ContractRef arg -> FutureContract arg [unFutureContract] :: FutureContract arg -> ContractRef arg -- | Convert something to Address in Haskell world. -- -- Use this when you want to access state of the contract and are not -- interested in calling it. class ToAddress a toAddress :: ToAddress a => a -> Address -- | Convert something referring to a contract (not specific entrypoint) to -- TAddress in Haskell world. class ToTAddress cp a toTAddress :: ToTAddress cp a => a -> TAddress cp -- | Convert something to ContractRef in Haskell world. class ToContractRef cp contract toContractRef :: ToContractRef cp contract => contract -> ContractRef cp -- | Convert something from ContractAddr in Haskell world. class FromContractRef cp contract fromContractRef :: FromContractRef cp contract => ContractRef cp -> contract -- | Single entrypoint of a contract. -- -- Note that we cannot make it return [[Operation], store] -- because such entrypoint should've been followed by pair, and -- this is not possible if entrypoint implementation ends with -- failWith. type Entrypoint param store = '[param, store] :-> ContractOut store -- | Version of Entrypoint which accepts no argument. type Entrypoint_ store = '[store] :-> ContractOut store optimizeLorentz :: forall (inp :: [Type]) (out :: [Type]). (inp :-> out) -> inp :-> out optimizeLorentzWithConf :: forall (inp :: [Type]) (out :: [Type]). OptimizerConf -> (inp :-> out) -> inp :-> out -- | Lorentz version of transformBytes. transformBytesLorentz :: forall (inp :: [Type]) (out :: [Type]). Bool -> (ByteString -> ByteString) -> (inp :-> out) -> inp :-> out -- | Lorentz version of transformStrings. transformStringsLorentz :: forall (inp :: [Type]) (out :: [Type]). Bool -> (MText -> MText) -> (inp :-> out) -> inp :-> out -- | Parse textual representation of a Michelson value and turn it into -- corresponding Haskell value. -- -- Note: it won't work in some complex cases, e. g. if there is a lambda -- which uses an instruction which depends on current contract's type. -- Obviously it can not work, because we don't have any information about -- a contract to which this value belongs (there is no such contract at -- all). parseLorentzValue :: KnownValue v => Text -> Either ParseLorentzError v (#) :: forall (a :: [Type]) (b :: [Type]) (c :: [Type]). (a :-> b) -> (b :-> c) -> a :-> c infixl 8 # -- | Wrap Lorentz instruction with variable annotations, annots -- list has to be non-empty, otherwise this function raises an error. iWithVarAnnotations :: forall (inp :: [Type]) (out :: [Type]). HasCallStack => [Text] -> (inp :-> out) -> inp :-> out iForceNotFail :: forall (i :: [Type]) (o :: [Type]). (i :-> o) -> i :-> o iMapAnyCode :: forall (i1 :: [Type]) (i2 :: [Type]) (o :: [Type]). (forall (o' :: [T]). () => Instr (ToTs i1) o' -> Instr (ToTs i2) o') -> (i1 :-> o) -> i2 :-> o iNonFailingCode :: forall (inp :: [Type]) (out :: [Type]). HasCallStack => (inp :-> out) -> Instr (ToTs inp) (ToTs out) iAnyCode :: forall (inp :: [Type]) (out :: [Type]). (inp :-> out) -> Instr (ToTs inp) (ToTs out) iGenericIf :: forall (a :: [Type]) (b :: [Type]) (c :: [Type]) (s :: [Type]). (forall (s' :: [T]). () => Instr (ToTs a) s' -> Instr (ToTs b) s' -> Instr (ToTs c) s') -> (a :-> s) -> (b :-> s) -> c :-> s pattern I :: Instr (ToTs inp) (ToTs out) -> inp :-> out pattern FI :: (forall (out' :: [T]). () => Instr (ToTs inp) out') -> inp :-> out -- | Alias for instruction which hides inner types representation via -- T. newtype (inp :: [Type]) :-> (out :: [Type]) LorentzInstr :: RemFail Instr (ToTs inp) (ToTs out) -> (:->) (inp :: [Type]) (out :: [Type]) [unLorentzInstr] :: (:->) (inp :: [Type]) (out :: [Type]) -> RemFail Instr (ToTs inp) (ToTs out) infixr 1 :-> -- | Alias for :->, seems to make signatures more readable -- sometimes. -- -- Let's someday decide which one of these two should remain. type (%>) = (:->) infixr 1 %> type ContractOut st = '[([Operation], st)] type ContractCode cp st = '[(cp, st)] :-> ContractOut st data SomeContractCode [SomeContractCode] :: forall cp st. (NiceParameterFull cp, NiceStorage st) => ContractCode cp st -> SomeContractCode -- | An alias for :. -- -- We discourage its use as this hinders reading error messages (the -- compiler inserts unnecessary parentheses and indentation). type a & (b :: [Type]) = a : b infixr 2 & type Lambda i o = '[i] :-> '[o] -- | Applicable for wrappers over Lorentz code. class MapLorentzInstr instr -- | Modify all the code under given entity. mapLorentzInstr :: MapLorentzInstr instr => (forall (i :: [Type]) (o :: [Type]). () => (i :-> o) -> i :-> o) -> instr -> instr -- | Constraint applied to a whole parameter type. type NiceParameterFull cp = (Typeable cp, ParameterDeclaresEntrypoints cp) -- | Universal entrypoint calling. parameterEntrypointCallCustom :: forall cp (mname :: Maybe Symbol). ParameterDeclaresEntrypoints cp => EntrypointRef mname -> EntrypointCall cp (GetEntrypointArgCustom cp mname) eprName :: forall (mname :: Maybe Symbol). EntrypointRef mname -> EpName -- | Call root entrypoint safely. sepcCallRootChecked :: (NiceParameter cp, ForbidExplicitDefaultEntrypoint cp) => SomeEntrypointCall cp -- | Call the default entrypoint. parameterEntrypointCallDefault :: ParameterDeclaresEntrypoints cp => EntrypointCall cp (GetDefaultEntrypointArg cp) -- | Prepare call to given entrypoint. -- -- This does not treat calls to default entrypoint in a special way. To -- call default entrypoint properly use -- parameterEntrypointCallDefault. parameterEntrypointCall :: forall cp (name :: Symbol). ParameterDeclaresEntrypoints cp => Label name -> EntrypointCall cp (GetEntrypointArg cp name) -- | Derive annotations for given parameter. parameterEntrypointsToNotes :: ParameterDeclaresEntrypoints cp => ParamNotes (ToT cp) -- | Get entrypoint argument by name. type family EpdLookupEntrypoint (deriv :: k) cp :: Symbol -> Exp Maybe Type -- | Name and argument of each entrypoint. This may include intermediate -- ones, even root if necessary. -- -- Touching this type family is costly (O(N^2)), don't use it -- often. -- -- Note [order of entrypoints children]: If this contains entrypoints -- referring to indermediate nodes (not leaves) in or tree, then -- each such entrypoint should be mentioned eariler than all of its -- children. type family EpdAllEntrypoints (deriv :: k) cp :: [(Symbol, Type)] -- | Defines a generalized way to declare entrypoints for various parameter -- types. -- -- When defining instances of this typeclass, set concrete deriv -- argument and leave variable cp argument. Also keep in mind, -- that in presence of explicit default entrypoint, all other Or -- arms should be callable, though you can put this burden on user if -- very necessary. -- -- Methods of this typeclass aim to better type-safety when making up an -- implementation and they may be not too convenient to use; users should -- exploit their counterparts. class EntrypointsDerivation (deriv :: k) cp where { -- | Name and argument of each entrypoint. This may include intermediate -- ones, even root if necessary. -- -- Touching this type family is costly (O(N^2)), don't use it -- often. -- -- Note [order of entrypoints children]: If this contains entrypoints -- referring to indermediate nodes (not leaves) in or tree, then -- each such entrypoint should be mentioned eariler than all of its -- children. type family EpdAllEntrypoints (deriv :: k) cp :: [(Symbol, Type)]; -- | Get entrypoint argument by name. type family EpdLookupEntrypoint (deriv :: k) cp :: Symbol -> Exp Maybe Type; } -- | Construct parameter annotations corresponding to expected entrypoints -- set. -- -- This method is implementation detail, for actual notes construction -- use parameterEntrypointsToNotes. epdNotes :: EntrypointsDerivation deriv cp => (Notes (ToT cp), RootAnn) -- | Construct entrypoint caller. -- -- This does not treat calls to default entrypoint in a special way. -- -- This method is implementation detail, for actual entrypoint lookup use -- parameterEntrypointCall. epdCall :: forall (name :: Symbol). (EntrypointsDerivation deriv cp, ParameterScope (ToT cp)) => Label name -> EpConstructionRes (ToT cp) (Eval (EpdLookupEntrypoint deriv cp name)) -- | Description of how each of the entrypoints is constructed. epdDescs :: EntrypointsDerivation deriv cp => Rec EpCallingDesc (EpdAllEntrypoints deriv cp) -- | Ensure that all declared entrypoints are unique. type RequireAllUniqueEntrypoints cp = RequireAllUniqueEntrypoints' ParameterEntrypointsDerivation cp cp type family ParameterEntrypointsDerivation cp -- | Which entrypoints given parameter declares. -- -- Note that usually this function should not be used as constraint, use -- ParameterDeclaresEntrypoints for this purpose. class (EntrypointsDerivation ParameterEntrypointsDerivation cp cp, RequireAllUniqueEntrypoints cp) => ParameterHasEntrypoints cp where { type family ParameterEntrypointsDerivation cp; } -- | Parameter declares some entrypoints. -- -- This is a version of ParameterHasEntrypoints which we actually -- use in constraints. When given type is a sum type or newtype, we refer -- to ParameterHasEntrypoints instance, otherwise this instance is -- not necessary. type ParameterDeclaresEntrypoints cp = (If CanHaveEntrypoints cp ParameterHasEntrypoints cp (), NiceParameter cp, EntrypointsDerivation GetParameterEpDerivation cp cp) -- | Get all entrypoints declared for parameter. type family AllParameterEntrypoints cp :: [(Symbol, Type)] -- | Lookup for entrypoint type by name. -- -- Does not treat default entrypoints in a special way. type family LookupParameterEntrypoint cp :: Symbol -> Exp Maybe Type -- | Get type of entrypoint with given name, fail if not found. type GetEntrypointArg cp (name :: Symbol) = Eval LiftM2 FromMaybe :: Type -> Maybe Type -> Type -> Type TError 'Text "Entrypoint not found: " :<>: 'ShowType name :$$: 'Text "In contract parameter `" :<>: 'ShowType cp :<>: 'Text "`" :: Type -> Type LookupParameterEntrypoint cp name -- | Get type of entrypoint with given name, fail if not found. type GetDefaultEntrypointArg cp = Eval LiftM2 FromMaybe :: Type -> Maybe Type -> Type -> Type Pure cp LookupParameterEntrypoint cp DefaultEpName -- | Ensure that there is no explicit "default" entrypoint. type ForbidExplicitDefaultEntrypoint cp = Eval LiftM3 UnMaybe :: Exp Constraint -> Type -> Exp Constraint -> Maybe Type -> Constraint -> Type Pure Pure () TError 'Text "Parameter used here must have no explicit \"default\" entrypoint" :$$: 'Text "In parameter type `" :<>: 'ShowType cp :<>: 'Text "`" :: Type -> Exp Constraint -> Type LookupParameterEntrypoint cp DefaultEpName -- | Similar to ForbidExplicitDefaultEntrypoint, but in a version -- which the compiler can work with (and which produces errors confusing -- for users :/) type NoExplicitDefaultEntrypoint cp = Eval LookupParameterEntrypoint cp DefaultEpName ~ 'Nothing :: Maybe Type -- | Which entrypoint to call. -- -- We intentionally distinguish default and non-default cases because -- this makes API more details-agnostic. data EntrypointRef (mname :: Maybe Symbol) -- | Call the default entrypoint, or root if no explicit default is -- assigned. [CallDefault] :: EntrypointRef ('Nothing :: Maybe Symbol) -- | Call the given entrypoint; calling default is not treated specially. -- You have to provide entrypoint name via passing it as type argument. -- -- Unfortunatelly, here we cannot accept a label because in most cases -- our entrypoints begin from capital letter (being derived from -- constructor name), while labels must start from a lower-case letter, -- and there is no way to make a conversion at type-level. [Call] :: forall (name :: Symbol). NiceEntrypointName name => EntrypointRef ('Just name) -- | Universal entrypoint lookup. type family GetEntrypointArgCustom cp (mname :: Maybe Symbol) -- | When we call a Lorentz contract we should pass entrypoint name and -- corresponding argument. Ideally we want to statically check that -- parameter has entrypoint with given name and argument. Constraint -- defined by this type class holds for contract with parameter -- cp that have entrypoint matching name with type -- arg. -- -- In order to check this property statically, we need to know entrypoint -- name in compile time, EntrypointRef type serves this purpose. -- If entrypoint name is not known, one can use TrustEpName -- wrapper to take responsibility for presence of this entrypoint. -- -- If you want to call a function which has this constraint, you have two -- options: 1. Pass contract parameter cp using type -- application, pass EntrypointRef as a value and pass entrypoint -- argument. Type system will check that cp has an entrypoint -- with given reference and type. 2. Pass EpName wrapped into -- TrustEpName and entrypoint argument. In this case passing -- contract parameter is not necessary, you do not even have to know it. class HasEntrypointArg (cp :: k) name arg -- | Data returned by this method may look somewhat arbitrary. -- EpName is obviously needed because name can be -- EntrypointRef or TrustEpName. Dict is returned -- because in EntrypointRef case we get this evidence for free and -- don't want to use it. We seem to always need it anyway. useHasEntrypointArg :: HasEntrypointArg cp name arg => name -> (Dict (ParameterScope (ToT arg)), EpName) -- | HasEntrypointArg constraint specialized to default entrypoint. type HasDefEntrypointArg (cp :: k) defEpName defArg = (defEpName ~ EntrypointRef 'Nothing :: Maybe Symbol, HasEntrypointArg cp defEpName defArg) -- | This wrapper allows to pass untyped EpName and bypass checking -- that entrypoint with given name and type exists. newtype TrustEpName TrustEpName :: EpName -> TrustEpName -- | Checks that the given parameter consists of some specific entrypoint. -- Similar as HasEntrypointArg but ensures that the argument -- matches the following datatype. type HasEntrypointOfType param (con :: Symbol) exp = (GetEntrypointArgCustom param 'Just con ~ exp, ParameterDeclaresEntrypoints param) type (n :: Symbol) :> ty = 'NamedEp n ty infixr 0 :> -- | Check that the given entrypoint has some fields inside. This interface -- allows for an abstraction of contract parameter so that it requires -- some *minimal* specification, but not a concrete one. type family ParameterContainsEntrypoints param (fields :: [NamedEp]) -- | No entrypoints declared, parameter type will serve as argument type of -- the only existing entrypoint (default one). data EpdNone -- | A special type which wraps over a primitive type and states that it -- has entrypoints (one). -- -- Assuming that any type can have entrypoints makes use of Lorentz -- entrypoints too annoying, so for declaring entrypoints for not sum -- types we require an explicit wrapper. newtype ShouldHaveEntrypoints a ShouldHaveEntrypoints :: a -> ShouldHaveEntrypoints a [unHasEntrypoints] :: ShouldHaveEntrypoints a -> a nicePrintedValueEvi :: NicePrintedValue a :- PrintedValScope (ToT a) niceUnpackedValueEvi :: NiceUnpackedValue a :- UnpackedValScope (ToT a) nicePackedValueEvi :: NicePackedValue a :- PackedValScope (ToT a) niceConstantEvi :: NiceConstant a :- ConstantScope (ToT a) niceStorageEvi :: NiceStorage a :- StorageScope (ToT a) niceParameterEvi :: NiceParameter a :- ParameterScope (ToT a) -- | Gathers constraints, commonly required for values. class (IsoValue a, Typeable a) => KnownValue a -- | Ensure given type does not contain "operation". class (IsoValue a, ForbidOp ToT a) => NoOperation a class (IsoValue a, ForbidContract ToT a) => NoContractType a class (IsoValue a, ForbidBigMap ToT a) => NoBigMap a class (IsoValue a, HasNoNestedBigMaps ToT a) => CanHaveBigMap a -- | Constraint applied to any part of parameter type. -- -- Note that you don't usually apply this constraint to the whole -- parameter, consider using NiceParameterFull in such case. -- -- Using this type is justified e.g. when calling another contract, there -- you usually supply an entrypoint argument, not the whole parameter. type NiceParameter a = (KnownValue a, ProperParameterBetterErrors ToT a) type NiceStorage a = (HasAnnotation a, KnownValue a, ProperStorageBetterErrors ToT a) type NiceConstant a = (KnownValue a, ProperConstantBetterErrors ToT a) type NicePackedValue a = (KnownValue a, ProperPackedValBetterErrors ToT a) type NiceUnpackedValue a = (KnownValue a, ProperUnpackedValBetterErrors ToT a) type NiceFullPackedValue a = (NicePackedValue a, NiceUnpackedValue a) type NicePrintedValue a = (KnownValue a, ProperPrintedValBetterErrors ToT a) type NiceComparable n = (KnownValue n, Comparable ToT n) -- | This class defines the type and field annotations for a given type. -- Right now the type annotations come from names in a named field, and -- field annotations are generated from the record fields. class HasAnnotation a -- | A record is parameterized by a universe u, an interpretation -- f and a list of rows rs. The labels or indices of -- the record are given by inhabitants of the kind u; the type -- of values at any label r :: u is given by its interpretation -- f r :: *. data Rec (a :: u -> Type) (b :: [u]) [RNil] :: forall u (a :: u -> Type). Rec a ('[] :: [u]) [:&] :: forall u (a :: u -> Type) (r :: u) (rs :: [u]). !a r -> !Rec a rs -> Rec a (r : rs) infixr 7 :& -- | arg unwraps a named parameter with the specified name. One way -- to use it is to match on arguments with -XViewPatterns: -- --
-- fn (arg #t -> t) (arg #f -> f) = ... ---- -- This way, the names of parameters can be inferred from the patterns: -- no type signature for fn is required. In case a type -- signature for fn is provided, the parameters must come in the -- same order: -- --
-- fn :: "t" :! Integer -> "f" :! Integer -> ... -- fn (arg #t -> t) (arg #f -> f) = ... -- ok -- fn (arg #f -> f) (arg #t -> t) = ... -- does not typecheck --arg :: forall (name :: Symbol) a. Name name -> (name :! a) -> a -- | argF is similar to arg: it unwraps a named parameter -- with the specified name. The difference is that the result of -- argF is inside an arity wrapper, which is Identity for -- normal parameters and Maybe for optional parameters. argF :: forall (name :: Symbol) f a. Name name -> NamedF f a name -> f a -- | A variation of arg for optional arguments. Requires a default -- value to handle the case when the optional argument was omitted: -- --
-- fn (argDef #answer 42 -> ans) = ... ---- -- In case you want to get a value wrapped in Maybe instead, use -- argF or ArgF. argDef :: forall (name :: Symbol) a. Name name -> a -> (name :? a) -> a -- | Infix application. -- --
-- f :: Either String $ Maybe Int -- = -- f :: Either String (Maybe Int) --type (f :: k1 -> k) $ (a :: k1) = f a infixr 2 $ -- | undefined that leaves a warning in code on every usage. undefined :: forall (r :: RuntimeRep) (a :: TYPE r). HasCallStack => a -- | Infix notation for the type of a named parameter. type (name :: Symbol) :! a = NamedF Identity a name -- | Infix notation for the type of an optional named parameter. type (name :: Symbol) :? a = NamedF Maybe a name -- | In this strategy the desired depths of contructors (in the type tree) -- and fields (in each constructor's tree) are provided manually and -- simply checked against the number of actual constructors and fields. withDepths :: [CstrDepth] -> GenericStrategy -- | Strategy to make right-balanced instances (both in constructors and -- fields). rightBalanced :: GenericStrategy -- | Strategy to make left-balanced instances (both in constructors and -- fields). leftBalanced :: GenericStrategy -- | Strategy to make fully right-leaning instances (both in constructors -- and fields). rightComb :: GenericStrategy -- | Strategy to make fully left-leaning instances (both in constructors -- and fields). leftComb :: GenericStrategy -- | Helper for making a constructor depth. -- -- Note that this is only intended to be more readable than directly -- using a tuple with withDepths and for the ability to be used in -- places where RebindableSyntax overrides the number literal -- resolution. cstr :: forall (n :: Nat). KnownNat n => [Natural] -> CstrDepth -- | Helper for making a field depth. -- -- Note that this is only intended to be more readable than directly -- using a tuple with withDepths and for the ability to be used in -- places where RebindableSyntax overrides the number literal -- resolution. fld :: forall (n :: Nat). KnownNat n => Natural customGeneric :: String -> GenericStrategy -> Q [Dec] -- | A piece of markdown document. -- -- This is opposed to Text type, which in turn is not supposed to -- contain markup elements. type Markdown = Builder -- | Proxy for a label type that includes the KnownSymbol constraint data Label (name :: Symbol) [Label] :: forall (name :: Symbol). KnownSymbol name => Label name -- | Entrypoint name. -- -- There are two properties we care about: -- --
-- >>> [mt|Some text|]
-- MTextUnsafe { unMText = "Some text" }
--
--
-- -- >>> formatTimestamp [timestampQuote| 2019-02-21T16:54:12.2344523Z |] -- "2019-02-21T16:54:12Z" ---- -- Inspired by 'time-quote' library. timestampQuote :: QuasiQuoter -- | Data type corresponding to address structure in Tezos. data Address mkUType :: forall (x :: T). SingI x => Notes x -> Type -- | Address with optional entrypoint name attached to it. TODO: come up -- with better name? data EpAddress EpAddress :: Address -> EpName -> EpAddress -- | Address itself [eaAddress] :: EpAddress -> Address -- | Entrypoint name (might be empty) [eaEntrypoint] :: EpAddress -> EpName -- | Keeps documentation gathered for some piece of contract code. -- -- Used for building documentation of a contract. data ContractDoc ContractDoc :: DocBlock -> DocBlock -> Set SomeDocDefinitionItem -> Set DocItemId -> ContractDoc -- | All inlined doc items. [cdContents] :: ContractDoc -> DocBlock -- | Definitions used in document. -- -- Usually you put some large and repetitive descriptions here. This -- differs from the document content in that it contains sections which -- are always at top-level, disregard the nesting. -- -- All doc items which define docItemId method go here, and only -- they. [cdDefinitions] :: ContractDoc -> DocBlock -- | We remember all already declared entries to avoid cyclic dependencies -- in documentation items discovery. [cdDefinitionsSet] :: ContractDoc -> Set SomeDocDefinitionItem -- | We remember all already used identifiers. (Documentation naturally -- should not declare multiple items with the same identifier because -- that would make references to the respective anchors ambiguous). [cdDefinitionIds] :: ContractDoc -> Set DocItemId -- | A part of documentation to be grouped. Essentially incapsulates -- DocBlock. newtype SubDoc SubDoc :: DocBlock -> SubDoc -- | Several doc items of the same type. data DocSection DocSection :: (NonEmpty $ DocElem d) -> DocSection -- | A doc item which we store, along with related information. data DocElem d DocElem :: d -> Maybe SubDoc -> DocElem d -- | Doc item itself. [deItem] :: DocElem d -> d -- | Subdocumentation, if given item is a group. [deSub] :: DocElem d -> Maybe SubDoc -- | Hides some documentation item which is put to "definitions" section. data SomeDocDefinitionItem [SomeDocDefinitionItem] :: forall d. (DocItem d, DocItemPlacement d ~ 'DocItemInDefinitions) => d -> SomeDocDefinitionItem -- | Hides some documentation item. data SomeDocItem [SomeDocItem] :: forall d. DocItem d => d -> SomeDocItem -- | How to render section name. data DocSectionNameStyle -- | Suitable for block name. DocSectionNameBig :: DocSectionNameStyle -- | Suitable for subsection title within block. DocSectionNameSmall :: DocSectionNameStyle data DocItemRef (p :: DocItemPlacementKind) (r :: DocItemReferencedKind) [DocItemRef] :: DocItemId -> DocItemRef 'DocItemInDefinitions 'True [DocItemRefInlined] :: DocItemId -> DocItemRef 'DocItemInlined 'True [DocItemNoRef] :: DocItemRef 'DocItemInlined 'False -- | Where do we place given doc item. data DocItemPlacementKind -- | Placed in the document content itself. DocItemInlined :: DocItemPlacementKind -- | Placed in dedicated definitions section; can later be referenced. DocItemInDefinitions :: DocItemPlacementKind -- | Position of all doc items of some type. newtype DocItemPos DocItemPos :: (Natural, Text) -> DocItemPos -- | Some unique identifier of a doc item. -- -- All doc items which should be refer-able need to have this identifier. newtype DocItemId DocItemId :: Text -> DocItemId -- | A piece of documentation describing one property of a thing, be it a -- name or description of a contract, or an error throwable by given -- endpoint. -- -- Items of the same type appear close to each other in a rendered -- documentation and form a section. -- -- Doc items are later injected into a contract code via a dedicated -- nop-like instruction. Normally doc items which belong to one section -- appear in resulting doc in the same order in which they appeared in -- the contract. -- -- While documentation framework grows, this typeclass acquires more and -- more methods for fine tuning of existing rendering logic because we -- don't want to break backward compatibility, hope one day we will make -- everything concise :( E.g. all rendering and reording stuff could be -- merged in one method, and we could have several template -- implementations for it which would allow user to specify only stuff -- relevant to his case. class (Typeable d, DOrd d) => DocItem d where { -- | Defines where given doc item should be put. There are two options: 1. -- Inline right here (default behaviour); 2. Put into definitions -- section. -- -- Note that we require all doc items with "in definitions" placement to -- have Eq and Ord instances which comply the following -- law: if two documentation items describe the same entity or property, -- they should be considered equal. type family DocItemPlacement d :: DocItemPlacementKind; type family DocItemReferenced d :: DocItemReferencedKind; type DocItemPlacement d = 'DocItemInlined; type DocItemReferenced d = 'False; } -- | Position of this item in the resulting documentation; the smaller the -- value, the higher the section with this element will be placed. If the -- position is the same as other doc items, they will be placed base on -- their name, alphabetically. -- -- Documentation structure is not necessarily flat. If some doc item -- consolidates a whole documentation block within it, this block will -- have its own placement of items independent from outer parts of the -- doc. docItemPos :: DocItem d => Natural -- | When multiple items of the same type belong to one section, how this -- section will be called. -- -- If not provided, section will contain just untitled content. docItemSectionName :: DocItem d => Maybe Text -- | Description of a section. -- -- Can be used to mention some common things about all elements of this -- section. Markdown syntax is permitted here. docItemSectionDescription :: DocItem d => Maybe Markdown -- | How to render section name. -- -- Takes effect only if section name is set. docItemSectionNameStyle :: DocItem d => DocSectionNameStyle -- | Defines a function which constructs an unique identifier of given doc -- item, if it has been decided to put the doc item into definitions -- section. -- -- Identifier should be unique both among doc items of the same type and -- items of other types. Thus, consider using "typeId-contentId" pattern. docItemRef :: DocItem d => d -> DocItemRef (DocItemPlacement d) (DocItemReferenced d) -- | Render given doc item to Markdown, preferably one line, optionally -- with header. -- -- Accepts the smallest allowed level of header. (Using smaller value -- than provided one will interfere with existing headers thus delivering -- mess). docItemToMarkdown :: DocItem d => HeaderLevel -> d -> Markdown -- | Render table of contents entry for given doc item to Markdown. docItemToToc :: DocItem d => HeaderLevel -> d -> Markdown -- | All doc items which this doc item refers to. -- -- They will automatically be put to definitions as soon as given doc -- item is detected. docItemDependencies :: DocItem d => d -> [SomeDocDefinitionItem] -- | This function accepts doc items put under the same section in the -- order in which they appeared in the contract and returns their new -- desired order. It's also fine to use this function for filtering or -- merging doc items. -- -- Default implementation * leaves inlined items as is; * for items put -- to definitions, lexicographically sorts them by their id. docItemsOrder :: DocItem d => [d] -> [d] -- | Defines where given doc item should be put. There are two options: 1. -- Inline right here (default behaviour); 2. Put into definitions -- section. -- -- Note that we require all doc items with "in definitions" placement to -- have Eq and Ord instances which comply the following -- law: if two documentation items describe the same entity or property, -- they should be considered equal. type family DocItemPlacement d :: DocItemPlacementKind type family DocItemReferenced d :: DocItemReferencedKind -- | Generate DToc entry anchor from docItemRef. mdTocFromRef :: (DocItem d, DocItemReferenced d ~ 'True) => HeaderLevel -> Markdown -> d -> Markdown -- | Get doc item position at term-level. docItemPosition :: DocItem d => DocItemPos -- | Make a reference to doc item in definitions. docDefinitionRef :: (DocItem d, DocItemPlacement d ~ 'DocItemInDefinitions) => Markdown -> d -> Markdown -- | Reference to the given section. -- -- Will return Nothing if sections of given doc item type are -- not assumed to be referred outside. docItemSectionRef :: DocItem di => Maybe Markdown -- | Render documentation for SubDoc. subDocToMarkdown :: HeaderLevel -> SubDoc -> Markdown -- | A hand-made anchor. data DAnchor DAnchor :: Anchor -> DAnchor -- | Comment in the doc (mostly used for licenses) data DComment DComment :: Text -> DComment -- | Repository settings for DGitRevision. newtype GitRepoSettings GitRepoSettings :: (Text -> Text) -> GitRepoSettings -- | By commit sha make up a url to that commit in remote repository. [grsMkGitRevision] :: GitRepoSettings -> Text -> Text data DGitRevision DGitRevisionKnown :: DGitRevisionInfo -> DGitRevision DGitRevisionUnknown :: DGitRevision -- | Description of something. data DDescription DDescription :: Markdown -> DDescription -- | A function which groups a piece of doc under one doc item. type DocGrouping = SubDoc -> SomeDocItem -- | Render given contract documentation to markdown document. contractDocToMarkdown :: ContractDoc -> LText morleyRepoSettings :: GitRepoSettings -- | Make DGitRevision. -- --
-- >>> :t $mkDGitRevision -- GitRepoSettings -> DGitRevision --mkDGitRevision :: ExpQ type Operation = Operation' Instr type Value = Value' Instr newtype BigMap k v BigMap :: Map k v -> BigMap k v [unBigMap] :: BigMap k v -> Map k v -- | Since Contract name is used to designate contract code, lets -- call analogy of TContract type as follows. -- -- Note that type argument always designates an argument of entrypoint. -- If a contract has explicit default entrypoint (and no root -- entrypoint), ContractRef referring to it can never have the -- entire parameter as its type argument. data ContractRef arg ContractRef :: Address -> SomeEntrypointCall arg -> ContractRef arg [crAddress] :: ContractRef arg -> Address [crEntrypoint] :: ContractRef arg -> SomeEntrypointCall arg type WellTypedIsoValue a = (WellTyped ToT a, IsoValue a) type SomeEntrypointCall arg = SomeEntrypointCallT ToT arg type EntrypointCall param arg = EntrypointCallT ToT param ToT arg -- | Isomorphism between Michelson values and plain Haskell types. -- -- Default implementation of this typeclass converts ADTs to Michelson -- "pair"s and "or"s. class WellTypedToT a => IsoValue a where { -- | Type function that converts a regular Haskell type into a T -- type. type family ToT a :: T; type ToT a = GValueType Rep a; } -- | Converts a Haskell structure into Value representation. toVal :: IsoValue a => a -> Value (ToT a) -- | Converts a Value into Haskell type. fromVal :: IsoValue a => Value (ToT a) -> a -- | Type function that converts a regular Haskell type into a T -- type. type family ToT a :: T -- | Replace type argument of ContractAddr with isomorphic one. coerceContractRef :: ToT a ~ ToT b => ContractRef a -> ContractRef b -- | Constraint for instrConstruct and gInstrConstructStack. type InstrConstructC dt = (GenericIsoValue dt, GInstrConstruct Rep dt) -- | Types of all fields in a datatype. type ConstructorFieldTypes dt = GFieldTypes Rep dt -- | Require this type to be homomorphic. class IsHomomorphic (a :: k) -- | Require two types to be built from the same type constructor. -- -- E.g. HaveCommonTypeCtor (Maybe Integer) (Maybe Natural) is -- defined, while HaveCmmonTypeCtor (Maybe Integer) [Integer] is -- not. class HaveCommonTypeCtor (a :: k) (b :: k1) -- | Doc element with description of a type. data DType [DType] :: forall a. TypeHasDoc a => Proxy a -> DType -- | Data hides some type implementing TypeHasDoc. data SomeTypeWithDoc [SomeTypeWithDoc] :: forall td. TypeHasDoc td => Proxy td -> SomeTypeWithDoc -- | Description for a Haskell type appearing in documentation. class (Typeable a, SingI TypeDocFieldDescriptions a, FieldDescriptionsValid TypeDocFieldDescriptions a a) => TypeHasDoc a where { -- | Description of constructors and fields of a. -- -- See FieldDescriptions documentation for an example of usage. -- -- Descriptions will be checked at compile time to make sure that only -- existing constructors and fields are referenced. -- -- For that check to work instance Generic a is required -- whenever TypeDocFieldDescriptions is not empty. -- -- For implementation of the check see FieldDescriptionsValid type -- family. type family TypeDocFieldDescriptions a :: FieldDescriptions; type TypeDocFieldDescriptions a = '[] :: [(Symbol, (Maybe Symbol, [(Symbol, Symbol)]))]; } -- | Name of type as it appears in definitions section. -- -- Each type must have its own unique name because it will be used in -- identifier for references. -- -- Default definition derives name from Generics. If it does not fit, -- consider defining this function manually. (We tried using Data -- for this, but it produces names including module names which is not do -- we want). typeDocName :: TypeHasDoc a => Proxy a -> Text -- | Explanation of a type. Markdown formatting is allowed. typeDocMdDescription :: TypeHasDoc a => Markdown -- | How reference to this type is rendered, in Markdown. -- -- Examples: -- --
-- >>> Just 3 ^.. _Just -- [3] ---- -- Gathering all values in a list of tuples: -- --
-- >>> [(1,2),(3,4)] ^.. each.each -- [1,2,3,4] --(^..) :: s -> Getting (Endo [a]) s a -> [a] infixl 8 ^.. -- | set is a synonym for (.~). -- -- Setting the 1st component of a pair: -- --
-- set _1 :: x -> (a, b) -> (x, b) -- set _1 = \x t -> (x, snd t) ---- -- Using it to rewrite (<$): -- --
-- set mapped :: Functor f => a -> f b -> f a -- set mapped = (<$) --set :: ASetter s t a b -> b -> s -> t -- | (.~) assigns a value to the target. It's the same thing as -- using (%~) with const: -- --
-- l .~ x = l %~ const x ---- -- See set if you want a non-operator synonym. -- -- Here it is used to change 2 fields of a 3-tuple: -- --
-- >>> (0,0,0) & _1 .~ 1 & _3 .~ 3 -- (1,0,3) --(.~) :: ASetter s t a b -> b -> s -> t infixr 4 .~ -- | over is a synonym for (%~). -- -- Getting fmap in a roundabout way: -- --
-- over mapped :: Functor f => (a -> b) -> f a -> f b -- over mapped = fmap ---- -- Applying a function to both components of a pair: -- --
-- over both :: (a -> b) -> (a, a) -> (b, b) -- over both = \f t -> (f (fst t), f (snd t)) ---- -- Using over _2 as a replacement for -- second: -- --
-- >>> over _2 show (10,20) -- (10,"20") --over :: ASetter s t a b -> (a -> b) -> s -> t -- | Gives access to the 1st field of a tuple (up to 5-tuples). -- -- Getting the 1st component: -- --
-- >>> (1,2,3,4,5) ^. _1 -- 1 ---- -- Setting the 1st component: -- --
-- >>> (1,2,3) & _1 .~ 10 -- (10,2,3) ---- -- Note that this lens is lazy, and can set fields even of -- undefined: -- --
-- >>> set _1 10 undefined :: (Int, Int) -- (10,*** Exception: Prelude.undefined ---- -- This is done to avoid violating a lens law stating that you can get -- back what you put: -- --
-- >>> view _1 . set _1 10 $ (undefined :: (Int, Int)) -- 10 ---- -- The implementation (for 2-tuples) is: -- --
-- _1 f t = (,) <$> f (fst t) -- <*> pure (snd t) ---- -- or, alternatively, -- --
-- _1 f ~(a,b) = (\a' -> (a',b)) <$> f a ---- -- (where ~ means a lazy pattern). -- -- _2, _3, _4, and _5 are also available (see -- below). _1 :: Field1 s t a b => Lens s t a b _2 :: Field2 s t a b => Lens s t a b _3 :: Field3 s t a b => Lens s t a b _4 :: Field4 s t a b => Lens s t a b _5 :: Field5 s t a b => Lens s t a b -- | Lens s t a b is the lowest common denominator of a setter and -- a getter, something that has the power of both; it has a -- Functor constraint, and since both Const and -- Identity are functors, it can be used whenever a getter or a -- setter is needed. -- --
-- t pure ≡ pure -- fmap (t f) . t g ≡ getCompose . t (Compose . fmap f . g) ---- -- The 1st law states that you can't change the shape of the structure or -- do anything funny with elements (traverse elements which aren't in the -- structure, create new elements out of thin air, etc.). The 2nd law -- states that you should be able to fuse 2 identical traversals into -- one. For a more detailed explanation of the laws, see this blog -- post (if you prefer rambling blog posts), or The Essence Of The -- Iterator Pattern (if you prefer papers). -- -- Traversing any value twice is a violation of traversal laws. You can, -- however, traverse values in any order. type Traversal s t a b = forall (f :: Type -> Type). Applicative f => a -> f b -> s -> f t -- | This is a type alias for monomorphic traversals which don't change the -- type of the container (or of the values inside). type Traversal' s a = Traversal s s a a -- | Monadic state transformer. -- -- Maps an old state to a new state inside a state monad. The old state -- is thrown away. -- --
-- Main> :t modify ((+1) :: Int -> Int) -- modify (...) :: (MonadState Int a) => a () ---- -- This says that modify (+1) acts over any Monad that is a -- member of the MonadState class, with an Int state. modify :: MonadState s m => (s -> s) -> m () -- | Retrieves a function of the current environment. asks :: MonadReader r m => (r -> a) -> m a -- | The reader monad transformer, which adds a read-only environment to -- the given monad. -- -- The return function ignores the environment, while -- >>= passes the inherited environment to both -- subcomputations. newtype ReaderT r (m :: Type -> Type) a ReaderT :: (r -> m a) -> ReaderT r (m :: Type -> Type) a [runReaderT] :: ReaderT r (m :: Type -> Type) a -> r -> m a -- | preuse is (^?) (or preview) which implicitly -- operates on the state – it takes the state and applies a traversal (or -- fold) to it to extract the 1st element the traversal points at. -- --
-- preuse l = gets (preview l) --preuse :: MonadState s m => Getting (First a) s a -> m (Maybe a) -- | use is (^.) (or view) which implicitly operates -- on the state; for instance, if your state is a record containing a -- field foo, you can write -- --
-- x <- use foo ---- -- to extract foo from the state. In other words, use is -- the same as gets, but for getters instead of functions. -- -- The implementation of use is straightforward: -- --
-- use l = gets (view l) ---- -- If you need to extract something with a fold or traversal, you need -- preuse. use :: MonadState s m => Getting a s a -> m a -- | preview is a synonym for (^?), generalised for -- MonadReader (just like view, which is a synonym for -- (^.)). -- --
-- >>> preview each [1..5] -- Just 1 --preview :: MonadReader s m => Getting (First a) s a -> m (Maybe a) -- | view is a synonym for (^.), generalised for -- MonadReader (we are able to use it instead of (^.) since -- functions are instances of the MonadReader class): -- --
-- >>> view _1 (1, 2) -- 1 ---- -- When you're using Reader for config and your config type has -- lenses generated for it, most of the time you'll be using view -- instead of asks: -- --
-- doSomething :: (MonadReader Config m) => m Int -- doSomething = do -- thingy <- view setting1 -- same as “asks (^. setting1)” -- anotherThingy <- view setting2 -- ... --view :: MonadReader s m => Getting a s a -> m a -- | Map several constraints over several variables. -- --
-- f :: Each [Show, Read] [a, b] => a -> b -> String -- = -- f :: (Show a, Show b, Read a, Read b) => a -> b -> String ---- -- To specify list with single constraint / variable, don't forget to -- prefix it with ': -- --
-- f :: Each '[Show] [a, b] => a -> b -> String --type family Each (c :: [k -> Constraint]) (as :: [k]) -- | Shorter alias for pure (). -- --
-- >>> pass :: Maybe () -- Just () --pass :: Applicative f => f () -- | Stricter version of $ operator. Default Prelude defines this at -- the toplevel module, so we do as well. -- --
-- >>> const 3 $ Prelude.undefined -- 3 -- -- >>> const 3 $! Prelude.undefined -- *** Exception: Prelude.undefined -- ... --($!) :: (a -> b) -> a -> b infixr 0 $! -- | map generalized to Functor. -- --
-- >>> map not (Just True) -- Just False -- -- >>> map not [True,False,True,True] -- [False,True,False,False] --map :: Functor f => (a -> b) -> f a -> f b -- | Alias for fmap . fmap. Convenient to work with two nested -- Functors. -- --
-- >>> negate <<$>> Just [1,2,3] -- Just [-1,-2,-3] --(<<$>>) :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b) infixl 4 <<$>> -- | Lifted to MonadIO version of newEmptyMVar. newEmptyMVar :: MonadIO m => m (MVar a) -- | Lifted to MonadIO version of newMVar. newMVar :: MonadIO m => a -> m (MVar a) -- | Lifted to MonadIO version of putMVar. putMVar :: MonadIO m => MVar a -> a -> m () -- | Lifted to MonadIO version of readMVar. readMVar :: MonadIO m => MVar a -> m a -- | Lifted to MonadIO version of swapMVar. swapMVar :: MonadIO m => MVar a -> a -> m a -- | Lifted to MonadIO version of takeMVar. takeMVar :: MonadIO m => MVar a -> m a -- | Lifted to MonadIO version of tryPutMVar. tryPutMVar :: MonadIO m => MVar a -> a -> m Bool -- | Lifted to MonadIO version of tryReadMVar. tryReadMVar :: MonadIO m => MVar a -> m (Maybe a) -- | Lifted to MonadIO version of tryTakeMVar. tryTakeMVar :: MonadIO m => MVar a -> m (Maybe a) -- | Lifted to MonadIO version of atomically. atomically :: MonadIO m => STM a -> m a -- | Lifted to MonadIO version of newTVarIO. newTVarIO :: MonadIO m => a -> m (TVar a) -- | Lifted to MonadIO version of readTVarIO. readTVarIO :: MonadIO m => TVar a -> m a -- | Lifted version of exitWith. exitWith :: MonadIO m => ExitCode -> m a -- | Lifted version of exitFailure. exitFailure :: MonadIO m => m a -- | Lifted version of exitSuccess. exitSuccess :: MonadIO m => m a -- | Lifted version of die. die is available since base-4.8, -- but it's more convenient to redefine it instead of using CPP. die :: MonadIO m => String -> m a -- | Lifted version of appendFile. appendFile :: MonadIO m => FilePath -> Text -> m () -- | Lifted version of getLine. getLine :: MonadIO m => m Text -- | Lifted version of openFile. -- -- See also withFile for more information. openFile :: MonadIO m => FilePath -> IOMode -> m Handle -- | Close a file handle -- -- See also withFile for more information. hClose :: MonadIO m => Handle -> m () -- | Opens a file, manipulates it with the provided function and closes the -- handle before returning. The Handle can be written to using the -- hPutStr and hPutStrLn functions. -- -- withFile is essentially the bracket pattern, specialized -- to files. This should be preferred over openFile + -- hClose as it properly deals with (asynchronous) exceptions. In -- cases where withFile is insufficient, for instance because the -- it is not statically known when manipulating the Handle has -- finished, one should consider other safe paradigms for resource usage, -- such as the ResourceT transformer from the resourcet -- package, before resorting to openFile and hClose. withFile :: (MonadIO m, MonadMask m) => FilePath -> IOMode -> (Handle -> m a) -> m a -- | Lifted version of newIORef. newIORef :: MonadIO m => a -> m (IORef a) -- | Lifted version of readIORef. readIORef :: MonadIO m => IORef a -> m a -- | Lifted version of writeIORef. writeIORef :: MonadIO m => IORef a -> a -> m () -- | Lifted version of modifyIORef. modifyIORef :: MonadIO m => IORef a -> (a -> a) -> m () -- | Lifted version of modifyIORef'. modifyIORef' :: MonadIO m => IORef a -> (a -> a) -> m () -- | Lifted version of atomicModifyIORef. atomicModifyIORef :: MonadIO m => IORef a -> (a -> (a, b)) -> m b -- | Lifted version of atomicModifyIORef'. atomicModifyIORef' :: MonadIO m => IORef a -> (a -> (a, b)) -> m b -- | Lifted version of atomicWriteIORef. atomicWriteIORef :: MonadIO m => IORef a -> a -> m () -- | Specialized version of for_ for Maybe. It's used for -- code readability. Also helps to avoid space leaks: Foldable.mapM_ -- space leak. -- --
-- >>> whenJust Nothing $ \b -> print (not b) -- -- >>> whenJust (Just True) $ \b -> print (not b) -- False --whenJust :: Applicative f => Maybe a -> (a -> f ()) -> f () -- | Monadic version of whenJust. whenJustM :: Monad m => m (Maybe a) -> (a -> m ()) -> m () -- | Performs default Applicative action if Nothing is given. -- Otherwise returns content of Just pured to Applicative. -- --
-- >>> whenNothing Nothing [True, False] -- [True,False] -- -- >>> whenNothing (Just True) [True, False] -- [True] --whenNothing :: Applicative f => Maybe a -> f a -> f a -- | Performs default Applicative action if Nothing is given. -- Do nothing for Just. Convenient for discarding Just -- content. -- --
-- >>> whenNothing_ Nothing $ putTextLn "Nothing!" -- Nothing! -- -- >>> whenNothing_ (Just True) $ putTextLn "Nothing!" --whenNothing_ :: Applicative f => Maybe a -> f () -> f () -- | Monadic version of whenNothing. whenNothingM :: Monad m => m (Maybe a) -> m a -> m a -- | Monadic version of whenNothingM_. whenNothingM_ :: Monad m => m (Maybe a) -> m () -> m () -- | Extracts value from Left or return given default value. -- --
-- >>> fromLeft 0 (Left 3) -- 3 -- -- >>> fromLeft 0 (Right 5) -- 0 --fromLeft :: a -> Either a b -> a -- | Extracts value from Right or return given default value. -- --
-- >>> fromRight 0 (Left 3) -- 0 -- -- >>> fromRight 0 (Right 5) -- 5 --fromRight :: b -> Either a b -> b -- | Maps left part of Either to Maybe. -- --
-- >>> leftToMaybe (Left True) -- Just True -- -- >>> leftToMaybe (Right "aba") -- Nothing --leftToMaybe :: Either l r -> Maybe l -- | Maps right part of Either to Maybe. -- --
-- >>> rightToMaybe (Left True) -- Nothing -- -- >>> rightToMaybe (Right "aba") -- Just "aba" --rightToMaybe :: Either l r -> Maybe r -- | Maps Maybe to Either wrapping default value into -- Left. -- --
-- >>> maybeToRight True (Just "aba") -- Right "aba" -- -- >>> maybeToRight True Nothing -- Left True --maybeToRight :: l -> Maybe r -> Either l r -- | Maps Maybe to Either wrapping default value into -- Right. -- --
-- >>> maybeToLeft True (Just "aba") -- Left "aba" -- -- >>> maybeToLeft True Nothing -- Right True --maybeToLeft :: r -> Maybe l -> Either l r -- | Monadic version of whenLeft. whenLeftM :: Monad m => m (Either l r) -> (l -> m ()) -> m () -- | Monadic version of whenRight. whenRightM :: Monad m => m (Either l r) -> (r -> m ()) -> m () -- | Shorter and more readable alias for flip runReaderT. usingReaderT :: r -> ReaderT r m a -> m a -- | Shorter and more readable alias for flip runReader. usingReader :: r -> Reader r a -> a -- | Shorter and more readable alias for flip runStateT. usingStateT :: s -> StateT s m a -> m (a, s) -- | Shorter and more readable alias for flip runState. usingState :: s -> State s a -> (a, s) -- | Alias for flip evalStateT. It's not shorter but sometimes -- more readable. Done by analogy with using* functions family. evaluatingStateT :: Functor f => s -> StateT s f a -> f a -- | Alias for flip evalState. It's not shorter but sometimes more -- readable. Done by analogy with using* functions family. evaluatingState :: s -> State s a -> a -- | Alias for flip execStateT. It's not shorter but sometimes -- more readable. Done by analogy with using* functions family. executingStateT :: Functor f => s -> StateT s f a -> f s -- | Alias for flip execState. It's not shorter but sometimes more -- readable. Done by analogy with using* functions family. executingState :: s -> State s a -> s -- | Extracts Monoid value from Maybe returning mempty -- if Nothing. -- --
-- >>> maybeToMonoid (Just [1,2,3] :: Maybe [Int]) -- [1,2,3] -- -- >>> maybeToMonoid (Nothing :: Maybe [Int]) -- [] --maybeToMonoid :: Monoid m => Maybe m -> m -- | Type class for types that can be created from one element. -- singleton is lone name for this function. Also constructions -- of different type differ: :[] for lists, two arguments for -- Maps. Also some data types are monomorphic. -- --
-- >>> one True :: [Bool] -- [True] -- -- >>> one 'a' :: Text -- "a" -- -- >>> one (3, "hello") :: HashMap Int String -- fromList [(3,"hello")] --class One x where { type family OneItem x; } -- | Create a list, map, Text, etc from a single element. one :: One x => OneItem x -> x type family OneItem x -- | Very similar to Foldable but also allows instances for -- monomorphic types like Text but forbids instances for -- Maybe and similar. This class is used as a replacement for -- Foldable type class. It solves the following problems: -- --
-- >>> toList @Text "aba" -- "aba" -- -- >>> :t toList @Text "aba" -- toList @Text "aba" :: [Char] --toList :: Container t => t -> [Element t] -- | Checks whether container is empty. -- --
-- >>> null @Text "" -- True -- -- >>> null @Text "aba" -- False --null :: Container t => t -> Bool foldr :: Container t => (Element t -> b -> b) -> b -> t -> b foldl :: Container t => (b -> Element t -> b) -> b -> t -> b foldl' :: Container t => (b -> Element t -> b) -> b -> t -> b length :: Container t => t -> Int elem :: Container t => Element t -> t -> Bool maximum :: Container t => t -> Element t minimum :: Container t => t -> Element t foldMap :: (Container t, Monoid m) => (Element t -> m) -> t -> m fold :: Container t => t -> Element t foldr' :: Container t => (Element t -> b -> b) -> b -> t -> b foldr1 :: Container t => (Element t -> Element t -> Element t) -> t -> Element t foldl1 :: Container t => (Element t -> Element t -> Element t) -> t -> Element t notElem :: Container t => Element t -> t -> Bool all :: Container t => (Element t -> Bool) -> t -> Bool any :: Container t => (Element t -> Bool) -> t -> Bool find :: Container t => (Element t -> Bool) -> t -> Maybe (Element t) safeHead :: Container t => t -> Maybe (Element t) -- | Type of element for some container. Implemented as an asscociated type -- family because some containers are monomorphic over element type (like -- Text, IntSet, etc.) so we can't implement nice interface -- using old higher-kinded types approach. Implementing this as an -- associated type family instead of top-level family gives you more -- control over element types. type family Element t -- | Type class for data types that can be converted to List of Pairs. You -- can define ToPairs by just defining toPairs function. -- -- But the following laws should be met: -- --
-- toPairs m ≡ zip (keys m) (elems m) -- keys ≡ map fst . toPairs -- elems ≡ map snd . toPairs --class ToPairs t -- | Converts the structure to the list of the key-value pairs. -- >>> toPairs (HashMap.fromList [(a, "xxx"), -- (b, "yyy")]) [(a,"xxx"),(b,"yyy")] toPairs :: ToPairs t => t -> [(Key t, Val t)] -- | Converts the structure to the list of the keys. -- --
-- >>> keys (HashMap.fromList [('a', "xxx"), ('b', "yyy")])
-- "ab"
--
keys :: ToPairs t => t -> [Key t]
-- | Converts the structure to the list of the values.
--
--
-- >>> elems (HashMap.fromList [('a', "xxx"), ('b', "yyy")])
-- ["xxx","yyy"]
--
elems :: ToPairs t => t -> [Val t]
-- | Similar to foldl' but takes a function with its arguments
-- flipped.
--
-- -- >>> flipfoldl' (/) 5 [2,3] :: Rational -- 15 % 2 --flipfoldl' :: (Container t, Element t ~ a) => (a -> b -> b) -> b -> t -> b -- | Stricter version of sum. -- --
-- >>> sum [1..10] -- 55 -- -- >>> sum (Just 3) -- ... -- • Do not use 'Foldable' methods on Maybe -- Suggestions: -- Instead of -- for_ :: (Foldable t, Applicative f) => t a -> (a -> f b) -> f () -- use -- whenJust :: Applicative f => Maybe a -> (a -> f ()) -> f () -- whenRight :: Applicative f => Either l r -> (r -> f ()) -> f () -- ... -- Instead of -- fold :: (Foldable t, Monoid m) => t m -> m -- use -- maybeToMonoid :: Monoid m => Maybe m -> m -- ... --sum :: (Container t, Num (Element t)) => t -> Element t -- | Stricter version of product. -- --
-- >>> product [1..10] -- 3628800 -- -- >>> product (Right 3) -- ... -- • Do not use 'Foldable' methods on Either -- Suggestions: -- Instead of -- for_ :: (Foldable t, Applicative f) => t a -> (a -> f b) -> f () -- use -- whenJust :: Applicative f => Maybe a -> (a -> f ()) -> f () -- whenRight :: Applicative f => Either l r -> (r -> f ()) -> f () -- ... -- Instead of -- fold :: (Foldable t, Monoid m) => t m -> m -- use -- maybeToMonoid :: Monoid m => Maybe m -> m -- ... --product :: (Container t, Num (Element t)) => t -> Element t -- | Constrained to Container version of traverse_. -- --
-- >>> traverse_ putTextLn ["foo", "bar"] -- foo -- bar --traverse_ :: (Container t, Applicative f) => (Element t -> f b) -> t -> f () -- | Constrained to Container version of for_. -- --
-- >>> for_ [1 .. 5 :: Int] $ \i -> when (even i) (print i) -- 2 -- 4 --for_ :: (Container t, Applicative f) => t -> (Element t -> f b) -> f () -- | Constrained to Container version of mapM_. -- --
-- >>> mapM_ print [True, False] -- True -- False --mapM_ :: (Container t, Monad m) => (Element t -> m b) -> t -> m () -- | Constrained to Container version of forM_. -- --
-- >>> forM_ [True, False] print -- True -- False --forM_ :: (Container t, Monad m) => t -> (Element t -> m b) -> m () -- | Constrained to Container version of sequenceA_. -- --
-- >>> sequenceA_ [putTextLn "foo", print True] -- foo -- True --sequenceA_ :: (Container t, Applicative f, Element t ~ f a) => t -> f () -- | Constrained to Container version of sequence_. -- --
-- >>> sequence_ [putTextLn "foo", print True] -- foo -- True --sequence_ :: (Container t, Monad m, Element t ~ m a) => t -> m () -- | Constrained to Container version of asum. -- --
-- >>> asum [Nothing, Just [False, True], Nothing, Just [True]] -- Just [False,True] --asum :: (Container t, Alternative f, Element t ~ f a) => t -> f a -- | Lifting bind into a monad. Generalized version of concatMap -- that works with a monadic predicate. Old and simpler specialized to -- list version had next type: -- --
-- concatMapM :: Monad m => (a -> m [b]) -> [a] -> m [b] ---- -- Side note: previously it had type -- --
-- concatMapM :: (Applicative q, Monad m, Traversable m) -- => (a -> q (m b)) -> m a -> q (m b) ---- -- Such signature didn't allow to use this function when traversed -- container type and type of returned by function-argument differed. Now -- you can use it like e.g. -- --
-- concatMapM readFile files >>= putTextLn --concatMapM :: (Applicative f, Monoid m, Container (l m), Element (l m) ~ m, Traversable l) => (a -> f m) -> l a -> f m -- | Like concatMapM, but has its arguments flipped, so can be used -- instead of the common fmap concat $ forM pattern. concatForM :: (Applicative f, Monoid m, Container (l m), Element (l m) ~ m, Traversable l) => l a -> (a -> f m) -> f m -- | Monadic and constrained to Container version of and. -- --
-- >>> andM [Just True, Just False] -- Just False -- -- >>> andM [Just True] -- Just True -- -- >>> andM [Just True, Just False, Nothing] -- Just False -- -- >>> andM [Just True, Nothing] -- Nothing -- -- >>> andM [putTextLn "1" >> pure True, putTextLn "2" >> pure False, putTextLn "3" >> pure True] -- 1 -- 2 -- False --andM :: (Container f, Element f ~ m Bool, Monad m) => f -> m Bool -- | Monadic and constrained to Container version of or. -- --
-- >>> orM [Just True, Just False] -- Just True -- -- >>> orM [Just True, Nothing] -- Just True -- -- >>> orM [Nothing, Just True] -- Nothing --orM :: (Container f, Element f ~ m Bool, Monad m) => f -> m Bool -- | Monadic and constrained to Container version of all. -- --
-- >>> allM (readMaybe >=> pure . even) ["6", "10"] -- Just True -- -- >>> allM (readMaybe >=> pure . even) ["5", "aba"] -- Just False -- -- >>> allM (readMaybe >=> pure . even) ["aba", "10"] -- Nothing --allM :: (Container f, Monad m) => (Element f -> m Bool) -> f -> m Bool -- | Monadic and constrained to Container version of any. -- --
-- >>> anyM (readMaybe >=> pure . even) ["5", "10"] -- Just True -- -- >>> anyM (readMaybe >=> pure . even) ["10", "aba"] -- Just True -- -- >>> anyM (readMaybe >=> pure . even) ["aba", "10"] -- Nothing --anyM :: (Container f, Monad m) => (Element f -> m Bool) -> f -> m Bool -- | Destructuring list into its head and tail if possible. This function -- is total. -- --
-- >>> uncons [] -- Nothing -- -- >>> uncons [1..5] -- Just (1,[2,3,4,5]) -- -- >>> uncons (5 : [1..5]) >>= \(f, l) -> pure $ f == length l -- Just True --uncons :: [a] -> Maybe (a, [a]) -- | Performs given action over NonEmpty list if given list is non -- empty. -- --
-- >>> whenNotNull [] $ \(b :| _) -> print (not b) -- -- >>> whenNotNull [False,True] $ \(b :| _) -> print (not b) -- True --whenNotNull :: Applicative f => [a] -> (NonEmpty a -> f ()) -> f () -- | Monadic version of whenNotNull. whenNotNullM :: Monad m => m [a] -> (NonEmpty a -> m ()) -> m () -- | Type that represents exceptions used in cases when a particular -- codepath is not meant to be ever executed, but happens to be executed -- anyway. data Bug Bug :: SomeException -> CallStack -> Bug -- | Pattern synonym to easy pattern matching on exceptions. So intead of -- writing something like this: -- --
-- isNonCriticalExc e
-- | Just (_ :: NodeAttackedError) <- fromException e = True
-- | Just DialogUnexpected{} <- fromException e = True
-- | otherwise = False
--
--
-- you can use Exc pattern synonym:
--
--
-- isNonCriticalExc = case
-- Exc (_ :: NodeAttackedError) -> True -- matching all exceptions of type NodeAttackedError
-- Exc DialogUnexpected{} -> True
-- _ -> False
--
--
-- This pattern is bidirectional. You can use Exc e instead of
-- toException e.
pattern Exc :: Exception e => e -> SomeException
-- | Generate a pure value which, when forced, will synchronously throw the
-- exception wrapped into Bug data type.
bug :: (HasCallStack, Exception e) => e -> a
-- | Throws error for Maybe if Nothing is given. Operates
-- over MonadError.
note :: MonadError e m => e -> Maybe a -> m a
-- | Lifted alias for evaluate with clearer name.
evaluateWHNF :: MonadIO m => a -> m a
-- | Like evaluateWNHF but discards value.
evaluateWHNF_ :: MonadIO m => a -> m ()
-- | Alias for evaluateWHNF . force with clearer name.
evaluateNF :: (NFData a, MonadIO m) => a -> m a
-- | Alias for evaluateWHNF . rnf. Similar to evaluateNF
-- but discards resulting value.
evaluateNF_ :: (NFData a, MonadIO m) => a -> m ()
-- | Monadic version of when.
--
--
-- >>> whenM (pure False) $ putTextLn "No text :("
--
-- >>> whenM (pure True) $ putTextLn "Yes text :)"
-- Yes text :)
--
-- >>> whenM (Just True) (pure ())
-- Just ()
--
-- >>> whenM (Just False) (pure ())
-- Just ()
--
-- >>> whenM Nothing (pure ())
-- Nothing
--
whenM :: Monad m => m Bool -> m () -> m ()
-- | Monadic version of unless.
--
--
-- >>> unlessM (pure False) $ putTextLn "No text :("
-- No text :(
--
-- >>> unlessM (pure True) $ putTextLn "Yes text :)"
--
unlessM :: Monad m => m Bool -> m () -> m ()
-- | Monadic version of if-then-else.
--
-- -- >>> ifM (pure True) (putTextLn "True text") (putTextLn "False text") -- True text --ifM :: Monad m => m Bool -> m a -> m a -> m a -- | Monadic version of guard. Occasionally useful. Here some -- complex but real-life example: -- --
-- findSomePath :: IO (Maybe FilePath) -- -- somePath :: MaybeT IO FilePath -- somePath = do -- path <- MaybeT findSomePath -- guardM $ liftIO $ doesDirectoryExist path -- return path --guardM :: MonadPlus m => m Bool -> m () -- | Like nub but runs in O(n * log n) time and requires -- Ord. -- --
-- >>> ordNub [3, 3, 3, 2, 2, -1, 1] -- [3,2,-1,1] --ordNub :: Ord a => [a] -> [a] -- | Like nub but runs in O(n * log_16(n)) time and -- requires Hashable. -- --
-- >>> hashNub [3, 3, 3, 2, 2, -1, 1] -- [3,2,-1,1] --hashNub :: (Eq a, Hashable a) => [a] -> [a] -- | Like ordNub but also sorts a list. -- --
-- >>> sortNub [3, 3, 3, 2, 2, -1, 1] -- [-1,1,2,3] --sortNub :: Ord a => [a] -> [a] -- | Like hashNub but has better performance and also doesn't save -- the order. -- --
-- >>> unstableNub [3, 3, 3, 2, 2, -1, 1] -- [1,2,3,-1] --unstableNub :: (Eq a, Hashable a) => [a] -> [a] -- | Support class to overload writing of string like values. class Print a -- | Write a string like value a to a supplied Handle. hPutStr :: (Print a, MonadIO m) => Handle -> a -> m () -- | Write a string like value a to a supplied Handle, -- appending a newline character. hPutStrLn :: (Print a, MonadIO m) => Handle -> a -> m () -- | Write a string like value to stdout/. putStr :: (Print a, MonadIO m) => a -> m () -- | Write a string like value to stdout appending a newline -- character. putStrLn :: (Print a, MonadIO m) => a -> m () -- | Lifted version of print. print :: forall a m. (MonadIO m, Show a) => a -> m () -- | Lifted version of hPrint hPrint :: (MonadIO m, Show a) => Handle -> a -> m () -- | Specialized to Text version of putStr or forcing type -- inference. putText :: MonadIO m => Text -> m () -- | Specialized to Text version of putStrLn or forcing type -- inference. putTextLn :: MonadIO m => Text -> m () -- | Specialized to Text version of putStr or forcing type -- inference. putLText :: MonadIO m => Text -> m () -- | Specialized to Text version of putStrLn or forcing type -- inference. putLTextLn :: MonadIO m => Text -> m () -- | Similar to undefined but data type. data Undefined Undefined :: Undefined -- | Version of trace that leaves a warning and takes Text. trace :: Text -> a -> a -- | Version of traceShow that leaves a warning. traceShow :: Show a => a -> b -> b -- | Version of traceShowId that leaves a warning. traceShowId :: Show a => a -> a -- | Version of traceId that leaves a warning. Useful to tag printed -- data, for instance: -- --
-- traceIdWith (x -> "My data: " <> show x) (veryLargeExpression) ---- -- This is especially useful with custom formatters: -- --
-- traceIdWith (x -> "My data: " <> pretty x) (veryLargeExpression) --traceIdWith :: (a -> Text) -> a -> a -- | Version of traceShowId that leaves a warning. Useful to tag -- printed data, for instance: -- --
-- traceShowIdWith ("My data: ", ) (veryLargeExpression)
--
traceShowIdWith :: Show s => (a -> s) -> a -> a
-- | Version of traceShowM that leaves a warning.
traceShowM :: (Show a, Monad m) => a -> m ()
-- | Version of traceM that leaves a warning and takes Text.
traceM :: Monad m => Text -> m ()
-- | Version of traceId that leaves a warning.
traceId :: Text -> Text
-- | Type class for converting other strings to String.
class ToString a
toString :: ToString a => a -> String
-- | Type class for converting other strings to Text.
class ToLText a
toLText :: ToLText a => a -> Text
-- | Type class for converting other strings to Text.
class ToText a
toText :: ToText a => a -> Text
-- | Type class for conversion to utf8 representation of text.
class ConvertUtf8 a b
-- | Encode as utf8 string (usually ByteString).
--
-- -- >>> encodeUtf8 @Text @ByteString "патак" -- "\208\191\208\176\209\130\208\176\208\186" --encodeUtf8 :: ConvertUtf8 a b => a -> b -- | Decode from utf8 string. -- --
-- >>> decodeUtf8 @Text @ByteString "\208\191\208\176\209\130\208\176\208\186" -- "\1087\1072\1090\1072\1082" -- -- >>> putStrLn $ decodeUtf8 @Text @ByteString "\208\191\208\176\209\130\208\176\208\186" -- патак --decodeUtf8 :: ConvertUtf8 a b => b -> a -- | Decode as utf8 string but returning execption if byte sequence is -- malformed. -- --
-- >>> decodeUtf8 @Text @ByteString "\208\208\176\209\130\208\176\208\186" -- "\65533\1072\1090\1072\1082" ---- --
-- >>> decodeUtf8Strict @Text @ByteString "\208\208\176\209\130\208\176\208\186" -- Left Cannot decode byte '\xd0': Data.Text.Internal.Encoding.decodeUtf8: Invalid UTF-8 stream --decodeUtf8Strict :: ConvertUtf8 a b => b -> Either UnicodeException a -- | Type synonym for ByteString. type LByteString = ByteString -- | Type synonym for Text. type LText = Text -- | Polymorhpic version of readEither. -- --
-- >>> readEither @Text @Int "123" -- Right 123 -- -- >>> readEither @Text @Int "aa" -- Left "Prelude.read: no parse" --readEither :: (ToString a, Read b) => a -> Either Text b -- | Generalized version of show. show :: forall b a. (Show a, IsString b) => a -> b -- | Map several constraints over a single variable. Note, that With a -- b ≡ Each a '[b] -- --
-- a :: With [Show, Read] a => a -> a -- = -- a :: (Show a, Read a) => a -> a --type With (a :: [k -> Constraint]) (b :: k) = a <+> b -- | This type class allows to implement variadic composition operator. class SuperComposition a b c | a b -> c -- | Allows to apply function to result of another function with multiple -- arguments. -- --
-- >>> (show ... (+)) 1 2 -- "3" -- -- >>> show ... 5 -- "5" -- -- >>> (null ... zip5) [1] [2] [3] [] [5] -- True ---- -- Inspired by -- http://stackoverflow.com/questions/9656797/variadic-compose-function. -- --
execStateT m s = liftM snd -- (runStateT m s)
evalStateT m s = liftM fst -- (runStateT m s)