Safe Haskell | Safe-Inferred |
---|---|
Language | GHC2021 |
This module implements a search in a typelevel tree
and offers a handy interface via -XOverloaedRecordDot
and HasField
.
We can search in the tree via BFS or DFS.
Performance wise this doesn't make a difference, as the search is performed at
compile time anyway however, it can change the semantics if the tree contains an
element more than once, see the example in getElem
.
Synopsis
- newtype Labeled l a = MkLabeled {
- unLabel :: a
- pattern HNodeL :: forall l a f ts. Functor f => f a -> HForest f ts -> HTree f ('TyNode (Labeled l a) ts)
- pattern HLeafL :: forall l a f. Functor f => f a -> HTree f ('TyNode (Labeled l a) '[])
- type TyNodeL l a = 'TyNode (Labeled l a)
- getElem :: forall {proxy} strat l typ t f. (HasField' (strat :: SearchStrategy) (Labeled l typ) t, Functor f) => proxy strat -> HTree f t -> f typ
- getElem' :: forall {proxy} strat typ t f. HasField' (strat :: SearchStrategy) typ t => proxy strat -> HTree f t -> f typ
- data SearchStrategy
- class HasField (x :: k) r a | x r -> a where
- getField :: r -> a
- data Proxy (t :: k) = Proxy
- class HasField' strat typ t | strat t -> typ where
- class Decide strat elem typ t | strat t -> typ where
- type family Elem typ t where ...
- type family AnyElem typ ts where ...
- getElemWithPath :: forall typ t f. Path typ t -> HTree f t -> f typ
Interface
Labeled types
a newtype that is labeled with some typelevel tag
Instances
Foldable (Labeled l2) Source # | |
Defined in Data.HTree.Labeled fold :: Monoid m => Labeled l2 m -> m # foldMap :: Monoid m => (a -> m) -> Labeled l2 a -> m # foldMap' :: Monoid m => (a -> m) -> Labeled l2 a -> m # foldr :: (a -> b -> b) -> b -> Labeled l2 a -> b # foldr' :: (a -> b -> b) -> b -> Labeled l2 a -> b # foldl :: (b -> a -> b) -> b -> Labeled l2 a -> b # foldl' :: (b -> a -> b) -> b -> Labeled l2 a -> b # foldr1 :: (a -> a -> a) -> Labeled l2 a -> a # foldl1 :: (a -> a -> a) -> Labeled l2 a -> a # toList :: Labeled l2 a -> [a] # null :: Labeled l2 a -> Bool # length :: Labeled l2 a -> Int # elem :: Eq a => a -> Labeled l2 a -> Bool # maximum :: Ord a => Labeled l2 a -> a # minimum :: Ord a => Labeled l2 a -> a # | |
Traversable (Labeled l2) Source # | |
Defined in Data.HTree.Labeled | |
Functor (Labeled l2) Source # | |
Generic (Labeled l2 a) Source # | |
Show a => Show (Labeled l2 a) Source # | |
Eq a => Eq (Labeled l2 a) Source # | |
Ord a => Ord (Labeled l2 a) Source # | |
Defined in Data.HTree.Labeled | |
type Rep (Labeled l2 a) Source # | |
Defined in Data.HTree.Labeled |
pattern HNodeL :: forall l a f ts. Functor f => f a -> HForest f ts -> HTree f ('TyNode (Labeled l a) ts) infixr 4 Source #
a pattern that allows for direct construction and destruction of nodes with labels
pattern HLeafL :: forall l a f. Functor f => f a -> HTree f ('TyNode (Labeled l a) '[]) Source #
a labeled HNode Leaf
type TyNodeL l a = 'TyNode (Labeled l a) infixr 4 Source #
a type syonym that allows for easy construction of TyTrees that have labeled nodes
Getting elements
getElem :: forall {proxy} strat l typ t f. (HasField' (strat :: SearchStrategy) (Labeled l typ) t, Functor f) => proxy strat -> HTree f t -> f typ Source #
searches a tree for an element and returns that element, specialised to Labeled
and unwraps
>>>
import Data.Functor.Identity
>>>
type T = TyNodeL "top" Int [ TyNodeL "inter" Int '[ TyNodeL "foo" Int '[]], TyNodeL "foo" Int '[]]
>>>
t :: HTree Identity T = 42 `HNodeL` HNodeL 4 (HNodeL 69 HNil `HCons` HNil) `HCons` HNodeL 67 HNil `HCons` HNil
>>>
getElem @'DFS @"foo" @Int Proxy t
Identity 69>>>
getElem @'BFS @"foo" @Int Proxy t
Identity 67
getElem' :: forall {proxy} strat typ t f. HasField' (strat :: SearchStrategy) typ t => proxy strat -> HTree f t -> f typ Source #
searches a tree for an element and returns that element
data SearchStrategy Source #
the search strategy used in HasField'
, this is intended to be used only as a DataKind
Reexports
class HasField (x :: k) r a | x r -> a where #
Constraint representing the fact that the field x
belongs to
the record type r
and has field type a
. This will be solved
automatically, but manual instances may be provided as well.
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,
is a safer alternative to the
Proxy
:: Proxy
a
idiom.undefined
:: a
>>>
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
Instances
Generic1 (Proxy :: k -> Type) | |
Foldable (Proxy :: Type -> Type) | Since: base-4.7.0.0 |
Defined in Data.Foldable fold :: Monoid m => Proxy m -> m # foldMap :: Monoid m => (a -> m) -> Proxy a -> m # foldMap' :: Monoid m => (a -> m) -> Proxy a -> m # foldr :: (a -> b -> b) -> b -> Proxy a -> b # foldr' :: (a -> b -> b) -> b -> Proxy a -> b # foldl :: (b -> a -> b) -> b -> Proxy a -> b # foldl' :: (b -> a -> b) -> b -> Proxy a -> b # foldr1 :: (a -> a -> a) -> Proxy a -> a # foldl1 :: (a -> a -> a) -> Proxy a -> a # elem :: Eq a => a -> Proxy a -> Bool # maximum :: Ord a => Proxy a -> a # minimum :: Ord a => Proxy a -> a # | |
Traversable (Proxy :: Type -> Type) | Since: base-4.7.0.0 |
Alternative (Proxy :: Type -> Type) | Since: base-4.9.0.0 |
Applicative (Proxy :: Type -> Type) | Since: base-4.7.0.0 |
Functor (Proxy :: Type -> Type) | Since: base-4.7.0.0 |
Monad (Proxy :: Type -> Type) | Since: base-4.7.0.0 |
MonadPlus (Proxy :: Type -> Type) | Since: base-4.9.0.0 |
Monoid (Proxy s) | Since: base-4.7.0.0 |
Semigroup (Proxy s) | Since: base-4.9.0.0 |
Bounded (Proxy t) | Since: base-4.7.0.0 |
Enum (Proxy s) | Since: base-4.7.0.0 |
Generic (Proxy t) | |
Ix (Proxy s) | Since: base-4.7.0.0 |
Defined in Data.Proxy | |
Read (Proxy t) | Since: base-4.7.0.0 |
Show (Proxy s) | Since: base-4.7.0.0 |
Eq (Proxy s) | Since: base-4.7.0.0 |
Ord (Proxy s) | Since: base-4.7.0.0 |
type Rep1 (Proxy :: k -> Type) | Since: base-4.6.0.0 |
type Rep (Proxy t) | Since: base-4.6.0.0 |
Internal
class HasField' strat typ t | strat t -> typ where Source #
This is the helper class that creates evidence, it implements a DFS together with Decide
Instances
HasField' 'BFS typ ('TyNode typ (t ': ts)) Source # | |
HasField' 'BFS typ ('TyNode typ ('[] :: [TyTree Type])) Source # | |
Decide 'BFS (AnyElem typ ts) typ ('TyNode typ' (t ': ts)) => HasField' 'BFS typ ('TyNode typ' (t ': ts)) Source # | |
HasField' 'DFS typ ('TyNode typ (t ': ts)) Source # | |
HasField' 'DFS typ ('TyNode typ ('[] :: [TyTree Type])) Source # | |
Decide 'DFS (Not (Elem typ t)) typ ('TyNode typ' (t ': ts)) => HasField' 'DFS typ ('TyNode typ' (t ': ts)) Source # | |
class Decide strat elem typ t | strat t -> typ where Source #
Together with HasField' implements a DFS in the tree
evidence' :: forall {proxy :: forall k. k -> Type}. proxy strat -> proxy elem -> Path typ t Source #
type family Elem typ t where ... Source #
simple typelevel predicate that tests whether some element is in a tree
type family AnyElem typ ts where ... Source #
typelevel predicate that tests whether the element is in any of the subtrees
getElemWithPath :: forall typ t f. Path typ t -> HTree f t -> f typ Source #
gets an element given a path into the tree