Copyright | (c) gspia 2020- |
---|---|
License | BSD |
Maintainer | gspia |
Safe Haskell | Safe |
Language | Haskell2010 |
Fcf.Alg.List
Type-level ListF
to be used with Cata, Ana and Hylo.
This module also contains other list-related functions (that might move to other place some day).
Synopsis
- data ListF a b
- data ListToFix :: [a] -> Exp (Fix (ListF a))
- data LenAlg :: Algebra (ListF a) Nat
- data SumAlg :: Algebra (ListF Nat) Nat
- data ProdAlg :: Algebra (ListF Nat) Nat
- data ListToParaFix :: [a] -> Exp (Fix (ListF (a, [a])))
- data DedupAlg :: RAlgebra (ListF (a, [a])) [a]
- data Sliding :: Nat -> [a] -> Exp [[a]]
- data SlidingAlg :: Nat -> RAlgebra (ListF (a, [a])) [[a]]
- data EvensStrip :: ListF a (Ann (ListF a) [a]) -> Exp [a]
- data EvensAlg :: ListF a (Ann (ListF a) [a]) -> Exp [a]
- data Evens :: [a] -> Exp [a]
- data NumIter :: a -> Nat -> Exp (Maybe (a, Nat))
- data ListRunAlg :: Nat -> Exp (Maybe (Nat, Nat))
- data RunInc :: Nat -> Exp [Nat]
- data Sum :: [Nat] -> Exp Nat
- data Partition :: (a -> Exp Bool) -> [a] -> Exp ([a], [a])
- data PartHelp :: (a -> Exp Bool) -> a -> ([a], [a]) -> Exp ([a], [a])
- data Intersperse :: a -> [a] -> Exp [a]
- data PrependToAll :: a -> [a] -> Exp [a]
- data Intercalate :: [a] -> [[a]] -> Exp [a]
- data Span :: (a -> Exp Bool) -> [a] -> Exp ([a], [a])
- data Break :: (a -> Exp Bool) -> [a] -> Exp ([a], [a])
- data IsPrefixOf :: [a] -> [a] -> Exp Bool
- type family IsPrefixOf_ (xs :: [a]) (ys :: [a]) :: Bool where ...
- data IsSuffixOf :: [a] -> [a] -> Exp Bool
- data IsInfixOf :: [a] -> [a] -> Exp Bool
- data Tails :: [a] -> Exp [[a]]
- data And :: [Bool] -> Exp Bool
- data All :: (a -> Exp Bool) -> [a] -> Exp Bool
- data Or :: [Bool] -> Exp Bool
- data Any :: (a -> Exp Bool) -> [a] -> Exp Bool
- data Snoc :: [a] -> a -> Exp [a]
- data ToList :: a -> Exp [a]
- data Equal :: [a] -> [a] -> Exp Bool
Documentation
>>>
import Fcf.Combinators
Base functor for a list of type [a]
.
Instances
type Eval (DedupAlg (ConsF ((,) a2 as) ((,) _fxs past)) :: [a1] -> Type) Source # | |
type Eval (DedupAlg (NilF :: ListF (a, [a]) (Fix (ListF (a, [a])), [a])) :: [a] -> Type) Source # | |
type Eval (EvensStrip (ConsF x y) :: [a] -> Type) Source # | |
Defined in Fcf.Alg.List | |
type Eval (EvensStrip (NilF :: ListF a (Ann (ListF a) [a])) :: [a] -> Type) Source # | |
Defined in Fcf.Alg.List | |
type Eval (EvensAlg (ConsF _ rst) :: [a] -> Type) Source # | |
type Eval (EvensAlg (NilF :: ListF a (Ann (ListF a) [a])) :: [a] -> Type) Source # | |
type Eval (ListToParaFix (a2 ': as) :: Fix (ListF (a1, [a1])) -> Type) Source # | |
Defined in Fcf.Alg.List type Eval (ListToParaFix (a2 ': as) :: Fix (ListF (a1, [a1])) -> Type) = Fix (ConsF ((,) a2 as) (Eval (ListToParaFix as))) | |
type Eval (ListToParaFix ([] :: [a]) :: Fix (ListF (a, [a])) -> Type) Source # | |
type Eval (ListToFix (a2 ': as) :: Fix (ListF a1) -> Type) Source # | |
type Eval (ListToFix ([] :: [a]) :: Fix (ListF a) -> Type) Source # | |
type Eval (SlidingAlg n (ConsF ((,) a2 as) ((,) _fxs past)) :: [[a1]] -> Type) Source # | |
Defined in Fcf.Alg.List | |
type Eval (SlidingAlg _ (NilF :: ListF (a, [a]) (Fix (ListF (a, [a])), [[a]])) :: [[a]] -> Type) Source # | |
Defined in Fcf.Alg.List | |
type Eval (Map f (ConsF a3 b2) :: ListF a2 b1 -> Type) Source # | |
type Eval (Map f (NilF :: ListF a2 a1) :: ListF a2 b -> Type) Source # | |
data ListToFix :: [a] -> Exp (Fix (ListF a)) Source #
ListToFix can be used to turn a norma type-level list into the base
functor type ListF, to be used with e.g. Cata. For examples in use, see
LenAlg
and SumAlg
.
Ideally, we would have one ToFix type-level function for which we could give type instances for different type-level types, like lists, trees etc. See TODO.md.
Example
>>>
:kind! Eval (ListToFix '[1,2,3])
Eval (ListToFix '[1,2,3]) :: Fix (ListF Nat) = 'Fix ('ConsF 1 ('Fix ('ConsF 2 ('Fix ('ConsF 3 ('Fix 'NilF))))))
data LenAlg :: Algebra (ListF a) Nat Source #
Example algebra to calculate list length.
Example
>>>
:kind! Eval (Cata LenAlg =<< ListToFix '[1,2,3])
Eval (Cata LenAlg =<< ListToFix '[1,2,3]) :: Nat = 3
data SumAlg :: Algebra (ListF Nat) Nat Source #
Example algebra to calculate the sum of Nats in a list.
Example
>>>
:kind! Eval (Cata SumAlg =<< ListToFix '[1,2,3,4])
Eval (Cata SumAlg =<< ListToFix '[1,2,3,4]) :: Nat = 10
data ProdAlg :: Algebra (ListF Nat) Nat Source #
Example algebra to calculate the prod of Nats in a list.
Example
>>>
:kind! Eval (Cata ProdAlg =<< ListToFix '[1,2,3,4])
Eval (Cata ProdAlg =<< ListToFix '[1,2,3,4]) :: Nat = 24
data ListToParaFix :: [a] -> Exp (Fix (ListF (a, [a]))) Source #
Form a Fix-structure that can be used with Para.
Example
>>>
:kind! Eval (ListToParaFix '[1,2,3])
Eval (ListToParaFix '[1,2,3]) :: Fix (ListF (Nat, [Nat])) = 'Fix ('ConsF '(1, '[2, 3]) ('Fix ('ConsF '(2, '[3]) ('Fix ('ConsF '(3, '[]) ('Fix 'NilF))))))
Instances
type Eval (ListToParaFix (a2 ': as) :: Fix (ListF (a1, [a1])) -> Type) Source # | |
Defined in Fcf.Alg.List type Eval (ListToParaFix (a2 ': as) :: Fix (ListF (a1, [a1])) -> Type) = Fix (ConsF ((,) a2 as) (Eval (ListToParaFix as))) | |
type Eval (ListToParaFix ([] :: [a]) :: Fix (ListF (a, [a])) -> Type) Source # | |
data DedupAlg :: RAlgebra (ListF (a, [a])) [a] Source #
Example from recursion-package by Vanessa McHale.
This removes duplicates from a list (by keeping the right-most one).
Example
>>>
:kind! Eval (Para DedupAlg =<< ListToParaFix '[1,1,3,2,5,1,3,2])
Eval (Para DedupAlg =<< ListToParaFix '[1,1,3,2,5,1,3,2]) :: [Nat] = '[5, 1, 3, 2]
data Sliding :: Nat -> [a] -> Exp [[a]] Source #
Example from Recursion Schemes by example by Tim Williams.
Example
>>>
:kind! Eval (Sliding 3 '[1,2,3,4,5,6])
Eval (Sliding 3 '[1,2,3,4,5,6]) :: [[Nat]] = '[ '[1, 2, 3], '[2, 3, 4], '[3, 4, 5], '[4, 5, 6], '[5, 6], '[6]]
data SlidingAlg :: Nat -> RAlgebra (ListF (a, [a])) [[a]] Source #
Tim Williams, Recursion Schemes by example, example for Para.
See Sliding
-function.
Instances
type Eval (SlidingAlg n (ConsF ((,) a2 as) ((,) _fxs past)) :: [[a1]] -> Type) Source # | |
Defined in Fcf.Alg.List | |
type Eval (SlidingAlg _ (NilF :: ListF (a, [a]) (Fix (ListF (a, [a])), [[a]])) :: [[a]] -> Type) Source # | |
Defined in Fcf.Alg.List |
data EvensStrip :: ListF a (Ann (ListF a) [a]) -> Exp [a] Source #
Tim Williams, Recursion Schemes by example, example for Histo.
Instances
type Eval (EvensStrip (ConsF x y) :: [a] -> Type) Source # | |
Defined in Fcf.Alg.List | |
type Eval (EvensStrip (NilF :: ListF a (Ann (ListF a) [a])) :: [a] -> Type) Source # | |
Defined in Fcf.Alg.List |
data EvensAlg :: ListF a (Ann (ListF a) [a]) -> Exp [a] Source #
Tim Williams, Recursion Schemes by example, example for Histo.
data Evens :: [a] -> Exp [a] Source #
This picks up the elements on even positions on a list and is an example on how to use Histo. This example is from Tim Williams, Recursion Schemes by example.
Example
>>>
:kind! Eval (Evens =<< RunInc 8)
Eval (Evens =<< RunInc 8) :: [Nat] = '[2, 4, 6, 8]
data RunInc :: Nat -> Exp [Nat] Source #
Construct a run (that is, a natuaral number sequence from 1 to arg).
Example
>>>
:kind! Eval (RunInc 8)
Eval (RunInc 8) :: [Nat] = '[1, 2, 3, 4, 5, 6, 7, 8]
data Sum :: [Nat] -> Exp Nat Source #
Sum a Nat-list.
Example
>>>
:kind! Eval (Sum '[1,2,3])
Eval (Sum '[1,2,3]) :: Nat = 6
data Partition :: (a -> Exp Bool) -> [a] -> Exp ([a], [a]) Source #
Partition
Example
>>>
:kind! Eval (Fcf.Alg.List.Partition ((>=) 35) '[ 20, 30, 40, 50])
Eval (Fcf.Alg.List.Partition ((>=) 35) '[ 20, 30, 40, 50]) :: ([Nat], [Nat]) = '( '[20, 30], '[40, 50])
data Intersperse :: a -> [a] -> Exp [a] Source #
Intersperse for type-level lists.
Example
>>>
:kind! Eval (Intersperse 0 '[1,2,3,4])
Eval (Intersperse 0 '[1,2,3,4]) :: [Nat] = '[1, 0, 2, 0, 3, 0, 4]
Instances
type Eval (Intersperse _ ([] :: [a]) :: [a] -> Type) Source # | |
Defined in Fcf.Alg.List | |
type Eval (Intersperse sep (x ': xs) :: [a] -> Type) Source # | |
Defined in Fcf.Alg.List |
data PrependToAll :: a -> [a] -> Exp [a] Source #
Instances
type Eval (PrependToAll sep (x ': xs) :: [a] -> Type) Source # | |
Defined in Fcf.Alg.List | |
type Eval (PrependToAll _ ([] :: [a]) :: [a] -> Type) Source # | |
Defined in Fcf.Alg.List |
data Intercalate :: [a] -> [[a]] -> Exp [a] Source #
Intercalate for type-level lists.
Example
>>>
:kind! Eval (Intercalate '[", "] '[ '["Lorem"], '["ipsum"], '["dolor"] ])
Eval (Intercalate '[", "] '[ '["Lorem"], '["ipsum"], '["dolor"] ]) :: [TL.Symbol] = '["Lorem", ", ", "ipsum", ", ", "dolor"]
Instances
type Eval (Intercalate xs xss :: [a] -> Type) Source # | |
Defined in Fcf.Alg.List type Eval (Intercalate xs xss :: [a] -> Type) = Eval ((Concat :: [[a]] -> [a] -> Type) =<< Intersperse xs xss) |
data Span :: (a -> Exp Bool) -> [a] -> Exp ([a], [a]) Source #
Span
, applied to a predicate p
and a type-level list xs
, returns a
type-level tuple where
first element is longest prefix (possibly empty) of xs
of elements that
satisfy p
and second element is the remainder of the list:
Example
>>>
:kind! Eval (Span (Flip (<) 3) '[1,2,3,4,1,2,3,4])
Eval (Span (Flip (<) 3) '[1,2,3,4,1,2,3,4]) :: ([Nat], [Nat]) = '( '[1, 2], '[3, 4, 1, 2, 3, 4])
>>>
:kind! Eval (Span (Flip (<) 9) '[1,2,3])
Eval (Span (Flip (<) 9) '[1,2,3]) :: ([Nat], [Nat]) = '( '[1, 2, 3], '[])
>>>
:kind! Eval (Span (Flip (<) 0) '[1,2,3])
Eval (Span (Flip (<) 0) '[1,2,3]) :: ([Nat], [Nat]) = '( '[], '[1, 2, 3])
data Break :: (a -> Exp Bool) -> [a] -> Exp ([a], [a]) Source #
Break
, applied to a predicate p
and a type-level list xs
, returns a
type-level 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:
Example
>>>
:kind! Eval (Break (Flip (>) 3) '[1,2,3,4,1,2,3,4])
Eval (Break (Flip (>) 3) '[1,2,3,4,1,2,3,4]) :: ([Nat], [Nat]) = '( '[1, 2, 3], '[4, 1, 2, 3, 4])
>>>
:kind! Eval (Break (Flip (<) 9) '[1,2,3])
Eval (Break (Flip (<) 9) '[1,2,3]) :: ([Nat], [Nat]) = '( '[], '[1, 2, 3])
>>>
:kind! Eval (Break (Flip (>) 9) '[1,2,3])
Eval (Break (Flip (>) 9) '[1,2,3]) :: ([Nat], [Nat]) = '( '[1, 2, 3], '[])
data IsPrefixOf :: [a] -> [a] -> Exp Bool Source #
IsPrefixOf takes two type-level lists and returns true iff the first list is a prefix of the second.
Example
>>>
:kind! Eval (IsPrefixOf '[0,1,2] '[0,1,2,3,4,5])
Eval (IsPrefixOf '[0,1,2] '[0,1,2,3,4,5]) :: Bool = 'True
>>>
:kind! Eval (IsPrefixOf '[0,1,2] '[0,1,3,2,4,5])
Eval (IsPrefixOf '[0,1,2] '[0,1,3,2,4,5]) :: Bool = 'False
>>>
:kind! Eval (IsPrefixOf '[] '[0,1,3,2,4,5])
Eval (IsPrefixOf '[] '[0,1,3,2,4,5]) :: Bool = 'True
>>>
:kind! Eval (IsPrefixOf '[0,1,3,2,4,5] '[])
Eval (IsPrefixOf '[0,1,3,2,4,5] '[]) :: Bool = 'False
Instances
type Eval (IsPrefixOf xs ys :: Bool -> Type) Source # | |
Defined in Fcf.Alg.List |
type family IsPrefixOf_ (xs :: [a]) (ys :: [a]) :: Bool where ... Source #
IsPrefixOf_ '[] _ = True | |
IsPrefixOf_ _ '[] = False | |
IsPrefixOf_ (x ': xs) (y ': ys) = Eval (Eval (TyEq x y) && IsPrefixOf_ xs ys) |
data IsSuffixOf :: [a] -> [a] -> Exp Bool Source #
IsSuffixOf take two type-level lists and returns true iff the first list is a suffix of the second.
Example
>>>
:kind! Eval (IsSuffixOf '[3,4,5] '[0,1,2,3,4,5])
Eval (IsSuffixOf '[3,4,5] '[0,1,2,3,4,5]) :: Bool = 'True
>>>
:kind! Eval (IsSuffixOf '[3,4,5] '[0,1,3,2,4,5])
Eval (IsSuffixOf '[3,4,5] '[0,1,3,2,4,5]) :: Bool = 'False
>>>
:kind! Eval (IsSuffixOf '[] '[0,1,3,2,4,5])
Eval (IsSuffixOf '[] '[0,1,3,2,4,5]) :: Bool = 'True
>>>
:kind! Eval (IsSuffixOf '[0,1,3,2,4,5] '[])
Eval (IsSuffixOf '[0,1,3,2,4,5] '[]) :: Bool = 'False
Instances
type Eval (IsSuffixOf xs ys :: Bool -> Type) Source # | |
Defined in Fcf.Alg.List |
data IsInfixOf :: [a] -> [a] -> Exp Bool Source #
IsInfixOf take two type-level lists and returns true iff the first list is a infix of the second.
Example
>>>
:kind! Eval (IsInfixOf '[2,3,4] '[0,1,2,3,4,5,6])
Eval (IsInfixOf '[2,3,4] '[0,1,2,3,4,5,6]) :: Bool = 'True
>>>
:kind! Eval (IsInfixOf '[2,4,4] '[0,1,2,3,4,5,6])
Eval (IsInfixOf '[2,4,4] '[0,1,2,3,4,5,6]) :: Bool = 'False
data Tails :: [a] -> Exp [[a]] Source #
Tails
Example
>>>
:kind! Eval (Tails '[0,1,2,3])
Eval (Tails '[0,1,2,3]) :: [[Nat]] = '[ '[0, 1, 2, 3], '[1, 2, 3], '[2, 3], '[3]]
data And :: [Bool] -> Exp Bool Source #
Give true if all of the booleans in the list are true.
Example
>>>
:kind! Eval (And '[ 'True, 'True])
Eval (And '[ 'True, 'True]) :: Bool = 'True
>>>
:kind! Eval (And '[ 'True, 'True, 'False])
Eval (And '[ 'True, 'True, 'False]) :: Bool = 'False
data All :: (a -> Exp Bool) -> [a] -> Exp Bool Source #
Type-level All.
Example
>>>
:kind! Eval (All (Flip (<) 6) '[0,1,2,3,4,5])
Eval (All (Flip (<) 6) '[0,1,2,3,4,5]) :: Bool = 'True
>>>
:kind! Eval (All (Flip (<) 5) '[0,1,2,3,4,5])
Eval (All (Flip (<) 5) '[0,1,2,3,4,5]) :: Bool = 'False
data Or :: [Bool] -> Exp Bool Source #
Give true if any of the booleans in the list is true.
Example
>>>
:kind! Eval (Or '[ 'True, 'True])
Eval (Or '[ 'True, 'True]) :: Bool = 'True
>>>
:kind! Eval (Or '[ 'False, 'False])
Eval (Or '[ 'False, 'False]) :: Bool = 'False
data Any :: (a -> Exp Bool) -> [a] -> Exp Bool Source #
Type-level Any.
Example
>>>
:kind! Eval (Any (Flip (<) 5) '[0,1,2,3,4,5])
Eval (Any (Flip (<) 5) '[0,1,2,3,4,5]) :: Bool = 'True
>>>
:kind! Eval (Any (Flip (<) 0) '[0,1,2,3,4,5])
Eval (Any (Flip (<) 0) '[0,1,2,3,4,5]) :: Bool = 'False
data Snoc :: [a] -> a -> Exp [a] Source #
Snoc for type-level lists.
Example
>>>
:kind! Eval (Snoc '[1,2,3] 4)
Eval (Snoc '[1,2,3] 4) :: [Nat] = '[1, 2, 3, 4]
data ToList :: a -> Exp [a] Source #
ToList for type-level lists.
Example
>>>
:kind! Eval (ToList 1)
Eval (ToList 1) :: [Nat] = '[1]