Maintainer | gatlin@niltag.net |
---|---|
Safe Haskell | Safe-Inferred |
Language | Haskell2010 |
A Sheet
is a multi-dimensional convolutional computational space.
The fabric of the universe comes in sheets like this but with a higher thread-
count.
Re-implementation of Kenneth Foner's ComonadSheet
library.
Some bug fixes and packaging upgrades have been made; additionally, for
idiosyncratic reasons, where possible functional dependencies have been replaced
with associated type families.
Synopsis
- evaluate :: ComonadApply w => w (w a -> a) -> w a
- evaluateF :: (ComonadApply w, Functor f) => w (f (w (f a) -> a)) -> w (f a)
- cell :: (Comonad w, Go r w) => RefList r -> w a -> a
- cells :: (Traversable t, Comonad w, Go r w) => t (RefList r) -> w a -> t a
- sheet :: (InsertNested l t, Applicative t, DimensionalAs x (t a), AsDimensionalAs x (t a) ~ l a) => a -> x -> t a
- change :: (InsertNested l w, ComonadApply w, DimensionalAs x (w (w a -> a)), AsDimensionalAs x (w (w a -> a)) ~ l (w a -> a)) => x -> w a -> w a
- sheetFromNested :: (InsertNested (Nested fs) (Nested (NestedNTimes (NestedCount fs) Tape)), Applicative (Nested (NestedNTimes (NestedCount fs) Tape))) => a -> Nested fs a -> Nested (NestedNTimes (NestedCount fs) Tape) a
- indexedSheet :: (InsertNested l (Nested ts), Applicative (Nested ts), DimensionalAs x (Nested ts a), AsDimensionalAs x (Nested ts a) ~ l a) => Coordinate (NestedCount ts) -> a -> x -> Indexed ts a
- data Stream t = Cons t (Stream t)
- (<:>) :: t -> Stream t -> Stream t
- repeat :: t -> Stream t
- zipWith :: (a -> b -> c) -> Stream a -> Stream b -> Stream c
- unzip :: Stream (a, b) -> (Stream a, Stream b)
- iterateStream :: (value -> value) -> value -> Stream value
- unfoldStream :: (state -> (value, state)) -> state -> Stream value
- takeStream :: Int -> Stream value -> [value]
- takeStreamNat :: Z < S n => Natural n -> Stream value -> [value]
- data Tape a = Tape {}
- tapeOf :: a -> Tape a
- moveL :: Tape a -> Tape a
- moveR :: Tape a -> Tape a
- iterate :: (t -> t) -> (t -> t) -> t -> Tape t
- enumerate :: Enum a => a -> Tape a
- unfold :: (c -> (a, c)) -> (c -> a) -> (c -> (a, c)) -> c -> Tape a
- data Ref (t :: RefType)
- getRef :: Ref t -> Int
- class CombineRefTypes (a :: RefType) (b :: RefType) where
- data RefType
- type RefList = Conic Ref
- class CombineRefLists as bs where
- merge :: ReifyNatural n => Counted n (Ref 'Relative) -> Counted n (Ref 'Absolute) -> Counted n (Ref 'Absolute)
- diff :: Counted n (Either (Ref 'Relative) (Ref 'Absolute)) -> Counted n (Ref 'Absolute) -> Counted n (Ref 'Relative)
- eitherFromRef :: Ref t -> Either (Ref 'Relative) (Ref 'Absolute)
- getMovement :: (Length ts <= n, ((n - Length ts) + Length ts) ~ n) => RefList ts -> Counted n (Ref 'Absolute) -> Counted n (Ref 'Relative)
- dimensional :: Tackable t (Replicate n 'Relative) => Natural (S n) -> Ref t -> RefList (Tack t (Replicate n 'Relative))
- type Coordinate n = Counted n (Ref 'Absolute)
- data Indexed ts a = Indexed {
- origin :: Coordinate (NestedCount ts)
- unindexed :: Nested ts a
- class Cross n t where
- cross :: Counted n (t a) -> Nested (NestedNTimes n t) (Counted n a)
- type Indexable ts = (Cross (NestedCount ts) Tape, ts ~ NestedNTimes (NestedCount ts) Tape)
- indices :: Cross n Tape => Coordinate n -> Nested (NestedNTimes n Tape) (Coordinate n)
- class Take r t where
- tapeTake :: Ref 'Relative -> Tape a -> [a]
- class View r t where
- type StreamFrom t a
- view :: RefList r -> t a -> StreamFrom t a
- tapeView :: Ref 'Relative -> Tape a -> Stream a
- class Go r t where
- tapeGo :: Ref 'Relative -> Tape a -> Tape a
- data Signed f a
- class InsertBase l where
- insertBase :: l a -> Tape a -> Tape a
- class InsertNested l t where
- insertNested :: l a -> t a -> t a
- type family AddNest x where ...
- type family AsNestedAs x y where ...
- class DimensionalAs (x :: Type) (y :: Type) where
- type AsDimensionalAs x y
- asDimensionalAs :: x -> y -> x `AsDimensionalAs` y
- slice :: (Take r' t, Go r t) => RefList r -> RefList r' -> t a -> ListFrom t a
- insert :: (DimensionalAs x (t a), InsertNested l t, AsDimensionalAs x (t a) ~ l a) => x -> t a -> t a
- type Abs1 = 'Absolute :-: Nil
- type Rel1 = 'Relative :-: Nil
- type Nat1 = S Z
- nat1 :: Natural Nat1
- type Sheet1 = Nested (NestedNTimes Nat1 Tape)
- type ISheet1 = Indexed (NestedNTimes Nat1 Tape)
- here1 :: RefList Rel1
- d1 :: CombineRefLists Rel1 x => RefList x -> RefList (Rel1 & x)
- columnAt :: Int -> RefList ('Absolute :-: Nil)
- column :: Z < NestedCount ts => Indexed ts x -> Int
- rightBy :: Int -> RefList Rel1
- leftBy :: Int -> RefList Rel1
- right :: RefList Rel1
- left :: RefList Rel1
- type Abs2 = 'Absolute :-: Abs1
- type Rel2 = 'Relative :-: Rel1
- type Nat2 = S Nat1
- nat2 :: Natural Nat2
- type Sheet2 = Nested (NestedNTimes Nat2 Tape)
- type ISheet2 = Indexed (NestedNTimes Nat2 Tape)
- here2 :: RefList Rel2
- d2 :: CombineRefLists Rel2 x => RefList x -> RefList (Rel2 & x)
- rowAt :: Int -> RefList (Tack 'Absolute Rel1)
- row :: Nat1 < NestedCount ts => Indexed ts x -> Int
- belowBy :: Int -> RefList Rel2
- aboveBy :: Int -> RefList Rel2
- above :: RefList Rel2
- below :: RefList Rel2
- type Abs3 = 'Absolute :-: Abs2
- type Rel3 = 'Relative :-: Rel2
- type Nat3 = S Nat2
- nat3 :: Natural Nat3
- type Sheet3 = Nested (NestedNTimes Nat3 Tape)
- type ISheet3 = Indexed (NestedNTimes Nat3 Tape)
- here3 :: RefList Rel3
- d3 :: CombineRefLists Rel3 x => RefList x -> RefList (Rel3 & x)
- levelAt :: Int -> RefList (Tack 'Absolute Rel2)
- level :: Nat2 < NestedCount ts => Indexed ts x -> Int
- outwardBy :: Int -> RefList Rel3
- inwardBy :: Int -> RefList Rel3
- outward :: RefList Rel3
- inward :: RefList Rel3
- type Abs4 = 'Absolute :-: Abs3
- type Rel4 = 'Relative :-: Rel3
- type Nat4 = S Nat3
- nat4 :: Natural Nat4
- type Sheet4 = Nested (NestedNTimes Nat4 Tape)
- type ISheet4 = Indexed (NestedNTimes Nat4 Tape)
- here4 :: RefList Rel4
- d4 :: CombineRefLists Rel4 x => RefList x -> RefList (Rel4 & x)
- spaceAt :: Int -> RefList (Tack 'Absolute Rel3)
- space :: Nat3 < NestedCount ts => Indexed ts x -> Int
- anaBy :: Int -> RefList Rel4
- cataBy :: Int -> RefList Rel4
- ana :: RefList Rel4
- cata :: RefList Rel4
- (&&&) :: (t -> a) -> (t -> b) -> t -> (a, b)
Defining and executing sheets.
sheet :: (InsertNested l t, Applicative t, DimensionalAs x (t a), AsDimensionalAs x (t a) ~ l a) => a -> x -> t a Source #
Construct a sheet of values from a default value and an insertable container of values.
change :: (InsertNested l w, ComonadApply w, DimensionalAs x (w (w a -> a)), AsDimensionalAs x (w (w a -> a)) ~ l (w a -> a)) => x -> w a -> w a Source #
sheetFromNested :: (InsertNested (Nested fs) (Nested (NestedNTimes (NestedCount fs) Tape)), Applicative (Nested (NestedNTimes (NestedCount fs) Tape))) => a -> Nested fs a -> Nested (NestedNTimes (NestedCount fs) Tape) a Source #
indexedSheet :: (InsertNested l (Nested ts), Applicative (Nested ts), DimensionalAs x (Nested ts a), AsDimensionalAs x (Nested ts a) ~ l a) => Coordinate (NestedCount ts) -> a -> x -> Indexed ts a Source #
Construct an indexed sheet from an origin index, a default value, and an insertable container of values.
Inexhaustible streams
A 'Stream t' is an inexhaustible source of values of type t
.
Unlike the ordinary builtin list type '[]' a Stream
cannot ever be empty
or exhausted.
zipWith :: (a -> b -> c) -> Stream a -> Stream b -> Stream c Source #
Combines two infinite streams element-wise using the provided function.
iterateStream :: (value -> value) -> value -> Stream value Source #
Repeatedly apply a step
function to an initial value
to generate the
next value
unfoldStream :: (state -> (value, state)) -> state -> Stream value Source #
takeStream :: Int -> Stream value -> [value] Source #
Capture n
values from an infinite 'Stream value'.
takeStreamNat :: Z < S n => Natural n -> Stream value -> [value] Source #
Alternate implementation of takeStream
which trades the inelegance but
convenience of error
for the type safety and inconvenience of requiring
some kind of evil type witness to convey how many items to grab from the
'Stream value'.
Tapes: bidirectional streams with a focus
Two infinite Stream
s of type a
joined with a center value in focus
.
A Tape
is named for tape in a Turing machine.
Instances
References, indices, and coordinates
data Ref (t :: RefType) Source #
A Ref
is indexed by a RefType
kind (confusing name, to be sure) and
represents some unique value. Here that unique value is carried by an Int
property.
An absolute reference denotes a coordinate in a fixed frame of reference.
A relative reference denotes some distance to be applied to another anchor
reference (relative or absolute).
Instances
getRef :: Ref t -> Int Source #
For when we want to throw away the type information and access the raw
Int
value beneath the Ref
.
class CombineRefTypes (a :: RefType) (b :: RefType) where Source #
Instances
Instances
Go ('Relative :-: Nil) (Nested (F Tape)) Source # | |
(Go rs (Nested ts), Functor (Nested ts)) => Go ('Relative :-: rs) (Nested (N ts Tape) :: Type -> Type) Source # | |
Take ('Relative :-: Nil) (Nested (F Tape)) Source # | |
(Functor (Nested ts), Take rs (Nested ts)) => Take ('Relative :-: rs) (Nested (N ts Tape)) Source # | |
View ('Relative :-: Nil) (Nested (F Tape)) Source # | |
(Functor (Nested ts), View rs (Nested ts)) => View ('Relative :-: rs) (Nested (N ts Tape)) Source # | |
(CombineRefTypes a b, CombineRefLists as bs) => CombineRefLists (a :-: as) (b :-: bs) Source # | |
Reference lists
class CombineRefLists as bs where Source #
We can combine lists of references if their corresponding elements can be combined. When combining two lists of references, any trailing elements from the longer list will be preserved at the end.
Instances
CombineRefLists Nil Nil Source # | |
CombineRefLists Nil (b :-: bs) Source # | |
CombineRefLists (a :-: as) Nil Source # | |
(CombineRefTypes a b, CombineRefLists as bs) => CombineRefLists (a :-: as) (b :-: bs) Source # | |
merge :: ReifyNatural n => Counted n (Ref 'Relative) -> Counted n (Ref 'Absolute) -> Counted n (Ref 'Absolute) Source #
Given a homogenous list of length n containing relative references, we can merge those relative positions with a homogenous list of absolute references.
diff :: Counted n (Either (Ref 'Relative) (Ref 'Absolute)) -> Counted n (Ref 'Absolute) -> Counted n (Ref 'Relative) Source #
Finds the relative movement necessary to move from a given absolute coordinate to the location specified by a list of a relative and absolute coordinates.
eitherFromRef :: Ref t -> Either (Ref 'Relative) (Ref 'Absolute) Source #
Given a Ref
, forget the type-level information about whether it's
absolute or relative by casting it into an Either type, with the left branch
holding relative reference and the right branch absolute.
getMovement :: (Length ts <= n, ((n - Length ts) + Length ts) ~ n) => RefList ts -> Counted n (Ref 'Absolute) -> Counted n (Ref 'Relative) Source #
Given a list of relative and absolute references (an n-dimensional reference) and an n-dimensional coordinate, we can obtain the relative movement necessary to get from the coordinate to the location specified by the references given.
dimensional :: Tackable t (Replicate n 'Relative) => Natural (S n) -> Ref t -> RefList (Tack t (Replicate n 'Relative)) Source #
Given a number n greater than zero and some reference, prepend (n - 1) relative references of value zero to the reference given, thus creating an n-dimensional reference where the references refers to the nth dimension.
Coordinates
A Nested
functor paired with a valid index
to one of its members.
Indexed | |
|
Instances
Indexed
type Indexable ts = (Cross (NestedCount ts) Tape, ts ~ NestedNTimes (NestedCount ts) Tape) Source #
indices :: Cross n Tape => Coordinate n -> Nested (NestedNTimes n Tape) (Coordinate n) Source #
Type-level Tape
manipulation with Coordinate
s and Ref
s.
Take
Instances
(Take Nil (Nested ts), Functor (Nested ts)) => Take Nil (Nested (N ts Tape)) Source # | |
(Take (Replicate (NestedCount ts) 'Relative) (Nested ts), Length r <= NestedCount ts, ((NestedCount ts - Length r) + Length r) ~ NestedCount ts) => Take r (Indexed ts) Source # | |
Take ('Relative :-: Nil) (Nested (F Tape)) Source # | |
(Functor (Nested ts), Take rs (Nested ts)) => Take ('Relative :-: rs) (Nested (N ts Tape)) Source # | |
View
type StreamFrom t a Source #
Type of an n-dimensional stream extracted from an n-dimensional sheet.
view :: RefList r -> t a -> StreamFrom t a Source #
Instances
View Nil (Nested (F Tape)) Source # | |
(View Nil (Nested ts), Functor (Nested ts)) => View Nil (Nested (N ts Tape)) Source # | |
(View (Replicate (NestedCount ts) 'Relative) (Nested ts), Length r <= NestedCount ts, ((NestedCount ts - Length r) + Length r) ~ NestedCount ts) => View r (Indexed ts) Source # | |
View ('Relative :-: Nil) (Nested (F Tape)) Source # | |
(Functor (Nested ts), View rs (Nested ts)) => View ('Relative :-: rs) (Nested (N ts Tape)) Source # | |
Go
Instances
Go Nil (Nested ts :: Type -> Type) Source # | |
(Go (Replicate (NestedCount ts) 'Relative) (Nested ts), Length r <= NestedCount ts, ((NestedCount ts - Length r) + Length r) ~ NestedCount ts, ReifyNatural (NestedCount ts)) => Go r (Indexed ts :: Type -> Type) Source # | |
Go ('Relative :-: Nil) (Nested (F Tape)) Source # | |
(Go rs (Nested ts), Functor (Nested ts)) => Go ('Relative :-: rs) (Nested (N ts Tape) :: Type -> Type) Source # | |
A Signed
f
is an 'f a' annotated with a sign: either Positive
or
Negative
. This is a useful type for specifying direction when inserting
into sheets. By wrapping a list or stream in Negative
and then inserting
it into a sheet, you insert it in the opposite direction of the usual one.
Instances
InsertBase (Signed Stream) Source # | |
InsertBase (Signed []) Source # | |
Show (f a) => Show (Signed f a) Source # | |
Eq (f a) => Eq (Signed f a) Source # | |
Ord (f a) => Ord (Signed f a) Source # | |
Defined in Sheet compare :: Signed f a -> Signed f a -> Ordering Source # (<) :: Signed f a -> Signed f a -> Bool Source # (<=) :: Signed f a -> Signed f a -> Bool Source # (>) :: Signed f a -> Signed f a -> Bool Source # (>=) :: Signed f a -> Signed f a -> Bool Source # |
Insertion
class InsertBase l where Source #
insertBase :: l a -> Tape a -> Tape a Source #
Instances
InsertBase Stream Source # | |
InsertBase Tape Source # | |
InsertBase [] Source # | |
InsertBase (Signed Stream) Source # | |
InsertBase (Signed []) Source # | |
class InsertNested l t where Source #
insertNested :: l a -> t a -> t a Source #
Instances
InsertNested l (Nested ts) => InsertNested (l :: Type -> Type) (Indexed ts :: Type -> Type) Source # | |
InsertBase l => InsertNested (Nested (F l) :: Type -> Type) (Nested (F Tape)) Source # | |
(InsertBase l, InsertNested (Nested ls) (Nested ts), Functor (Nested ls), Applicative (Nested ts)) => InsertNested (Nested (N ls l) :: Type -> Type) (Nested (N ts Tape) :: Type -> Type) Source # | |
type family AsNestedAs x y where ... Source #
AsNestedAs (f x) (Nested (F g) b) = Nested (F f) x | |
AsNestedAs x y = AddNest (x `AsNestedAs` UnNest y) |
Dimensions
class DimensionalAs (x :: Type) (y :: Type) where Source #
DimensionalAs
provides a mechanism to "lift" an n-deep nested structure
into an explicit Nested
type. This is the way in which raw
lists-of-lists-of-lists-, etc. can be inserted (without manual annotation of
nesting depth) into a sheet.
type AsDimensionalAs x y Source #
asDimensionalAs :: x -> y -> x `AsDimensionalAs` y Source #
Instances
(NestedAs x (Nested ts y), AsDimensionalAs x (Nested ts y) ~ AsNestedAs x (Nested ts y)) => DimensionalAs x (Nested ts y) Source # | |
Defined in Sheet type AsDimensionalAs x (Nested ts y) Source # asDimensionalAs :: x -> Nested ts y -> AsDimensionalAs x (Nested ts y) Source # | |
NestedAs x (Nested ts y) => DimensionalAs x (Indexed ts y) Source # | |
Defined in Sheet type AsDimensionalAs x (Indexed ts y) Source # asDimensionalAs :: x -> Indexed ts y -> AsDimensionalAs x (Indexed ts y) Source # |
insert :: (DimensionalAs x (t a), InsertNested l t, AsDimensionalAs x (t a) ~ l a) => x -> t a -> t a Source #
Insert a (possibly nested) list-like structure into a (possibly
many-dimensional) sheet.
The depth of the nesting structure being inserted must match the number of
dimensions of the sheet into which it is being inserted.
The structure being inserted need not be a Nested
type: it need only have
enough levels of structure (ie, number of nested lists) to match the
dimensionality of the sheet.