Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
This module defines a stream-like type named Replicator
, which is
mainly used in the definition of the Dupable
class to provide efficient linear duplication.
The API of Replicator
is close to the one of an infinite stream: it
can either produce a new value linearly (with next
or next#
), or be
linearly discarded (with consume
or extract
).
A crucial aspect, from a performance standpoint, is that the pure
function
(which takes an unrestricted argument) is implemented efficiently: the
Replicator
returns the same value on each call to next
. That is, the
pointer is always shared. This will allow Movable
types to be given an efficient instance of Dupable
.
Instances of both Movable
and
Dupable
typically involve deep copies. The
implementation of pure
lets us make sure that, for Movable
types, only one
deep copy is performed, rather than one per additional replica.
Strictly speaking, the implementation of (<*>)
plays a role in all this as
well:
For two pure
Replicators
fs
and as
, fs <*> as
is a pure
Replicator
. Together, pure
and (<*>)
form the
Applicative
instance of Replicator
.
Synopsis
- data Replicator a
- consume :: Replicator a %1 -> ()
- duplicate :: Replicator a %1 -> Replicator (Replicator a)
- map :: (a %1 -> b) -> Replicator a %1 -> Replicator b
- pure :: a -> Replicator a
- (<*>) :: Replicator (a %1 -> b) %1 -> Replicator a %1 -> Replicator b
- next :: Replicator a %1 -> (a, Replicator a)
- next# :: Replicator a %1 -> (# a, Replicator a #)
- take :: Int -> Replicator a %1 -> [a]
- extract :: Replicator a %1 -> a
- extend :: (Replicator a %1 -> b) -> Replicator a %1 -> Replicator b
- class Elim n a b
- elim :: forall (n :: Nat) a b f. (Elim (NatToPeano n) a b, IsFunN a b f, f ~ FunN (NatToPeano n) a b, n ~ Arity b f) => f %1 -> Replicator a %1 -> b
Documentation
data Replicator a Source #
Replicator
is a stream-like data structure used to linearly duplicate
values.
Instances
Applicative Replicator Source # | |
Defined in Data.Replicator.Linear.Internal.Instances pure :: a -> Replicator a Source # (<*>) :: Replicator (a %1 -> b) %1 -> Replicator a %1 -> Replicator b Source # liftA2 :: (a %1 -> b %1 -> c) -> Replicator a %1 -> Replicator b %1 -> Replicator c Source # | |
Functor Replicator Source # | |
Defined in Data.Replicator.Linear.Internal.Instances fmap :: (a %1 -> b) -> Replicator a %1 -> Replicator b Source # | |
Consumable (Replicator a) Source # | |
Defined in Data.Unrestricted.Linear.Internal.Consumable consume :: Replicator a %1 -> () Source # | |
Dupable (Replicator a) Source # | |
Defined in Data.Unrestricted.Linear.Internal.Dupable dupR :: Replicator a %1 -> Replicator (Replicator a) Source # dup2 :: Replicator a %1 -> (Replicator a, Replicator a) Source # |
consume :: Replicator a %1 -> () Source #
duplicate :: Replicator a %1 -> Replicator (Replicator a) Source #
map :: (a %1 -> b) -> Replicator a %1 -> Replicator b Source #
pure :: a -> Replicator a Source #
(<*>) :: Replicator (a %1 -> b) %1 -> Replicator a %1 -> Replicator b infixl 4 Source #
next :: Replicator a %1 -> (a, Replicator a) Source #
Extracts the next item from the "infinite stream"
.Replicator
a
next# :: Replicator a %1 -> (# a, Replicator a #) Source #
Extracts the next item from the "infinite stream"
.
Same function as Replicator
anext
, but returning an unboxed tuple.
take :: Int -> Replicator a %1 -> [a] Source #
is a list of size take
n asn
, containing n
replicas from as
.
extract :: Replicator a %1 -> a Source #
Returns the next item from
and efficiently consumes
the replicator at the same time.Replicator
a
extend :: (Replicator a %1 -> b) -> Replicator a %1 -> Replicator b Source #
Comonadic extend
function.
extend f = map f . duplicate
is used to implement Elim
n a belim
without recursion
so that we can guarantee that elim
will be inlined and unrolled.
elim'
Instances
Elim 'Z a b Source # | |
Defined in Data.Replicator.Linear.Internal elim' :: FunN 'Z a b %1 -> Replicator a %1 -> b | |
Elim ('S n) a b => Elim ('S ('S n)) a b Source # | |
Defined in Data.Replicator.Linear.Internal elim' :: FunN ('S ('S n)) a b %1 -> Replicator a %1 -> b | |
Elim ('S 'Z) a b Source # | |
Defined in Data.Replicator.Linear.Internal elim' :: FunN ('S 'Z) a b %1 -> Replicator a %1 -> b |
elim :: forall (n :: Nat) a b f. (Elim (NatToPeano n) a b, IsFunN a b f, f ~ FunN (NatToPeano n) a b, n ~ Arity b f) => f %1 -> Replicator a %1 -> b Source #
Takes a function of type a %1 -> a %1 -> ... %1 -> a %1 -> b
, and
returns a b
. The replicator is used to supply all the items of type a
required by the function.
For instance:
elim @1 :: (a %1 -> b) %1 -> Replicator a %1 -> b elim @2 :: (a %1 -> a %1 -> b) %1 -> Replicator a %1 -> b elim @3 :: (a %1 -> a %1 -> a %1 -> b) %1 -> Replicator a %1 -> b
It is not always necessary to give the arity argument. It can be inferred from the function argument.
elim (,) :: Replicator a %1 -> (a, a) elim (,,) :: Replicator a %1 -> (a, a, a)
About the constraints of this function (they won't get in your way):
provides the actual implementation ofElim
(NatToPeano
n) a belim
; there is an instance of this class for any(n, a, b)
indicate the shape ofIsFunN
a b f, f ~FunN
(NatToPeano
n) a b, n ~Arity
b ff
to the typechecker (see documentation ofIsFunN
).