Safe Haskell | Trustworthy |
---|---|
Language | Haskell2010 |
Reimagined approach for Foldable
type hierarchy. Forbids usages
of length
function and similar over Maybe
and other potentially unsafe
data types. It was proposed to use -XTypeApplication
for such cases.
But this approach is not robust enough because programmers are human and can
easily forget to do this. For discussion see this topic:
Suggest explicit type application for Foldable length and friends
- class ToList t where
- class ToPairs t where
- class ToList t => Container t where
- type ElementConstraint t :: * -> Constraint
- sum :: (Container t, Num (Element t)) => t -> Element t
- product :: (Container t, Num (Element t)) => t -> Element t
- mapM_ :: (Container t, Monad m) => (Element t -> m b) -> t -> m ()
- forM_ :: (Container t, Monad m) => t -> (Element t -> m b) -> m ()
- traverse_ :: (Container t, Applicative f) => (Element t -> f b) -> t -> f ()
- for_ :: (Container t, Applicative f) => t -> (Element t -> f b) -> f ()
- sequenceA_ :: (Container t, Applicative f, Element t ~ f a) => t -> f ()
- sequence_ :: (Container t, Monad m, Element t ~ m a) => t -> m ()
- asum :: (Container t, Alternative f, Element t ~ f a) => t -> f a
- class One x where
- type OneItem x
Foldable-like classes and methods
Type class for data types that can be converted to List.
Contains very small and safe subset of Foldable
functions.
You can define Tolist
by just defining toList
function.
But the following law should be met:
null
≡null
.toList
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.
toList :: t -> [Element t] Source #
Convert container to list of elements.
>>>
toList (Just True)
[True]>>>
toList @Text "aba"
"aba">>>
:t toList @Text "aba"
toList @Text "aba" :: [Char]
toList :: (Foldable f, t ~ f a, Element t ~ a) => t -> [Element t] Source #
Convert container to list of elements.
>>>
toList (Just True)
[True]>>>
toList @Text "aba"
"aba">>>
:t toList @Text "aba"
toList @Text "aba" :: [Char]
Checks whether container is empty.
>>>
null @Text ""
True>>>
null @Text "aba"
False
ToList ByteString Source # | |
ToList ByteString Source # | |
ToList IntSet Source # | |
ToList Text Source # | |
ToList Text Source # | |
ToList [a] Source # | |
ToList (Maybe a) Source # | |
ToList (NonEmpty a) Source # | |
ToList (ZipList a) Source # | |
ToList (Identity a) Source # | |
ToList (Dual a) Source # | |
ToList (Sum a) Source # | |
ToList (Product a) Source # | |
ToList (First a) Source # | |
ToList (Last a) Source # | |
ToList (IntMap v) Source # | |
ToList (Seq a) Source # | |
ToList (Set v) Source # | |
ToList (HashSet v) Source # | |
ToList (Vector a) Source # | |
ToList (Either a b) Source # | |
TypeError Constraint (DisallowInstance "tuples") => ToList (a, b) Source # | |
ToList (Map k v) Source # | |
ToList (HashMap k v) Source # | |
ToList (Const * a b) Source # | |
class ToPairs t where Source #
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
Type of keys of the mapping.
Type of value of the mapping.
toPairs :: t -> [(Key t, Val t)] Source #
Converts the structure to the list of the key-value pairs.
>>> import qualified Data.HashMap as HashMap
>>> toPairs (HashMap.fromList [(a
, "xxx"), (b
, "yyy")])
[(a
, "xxx"), (b
, "yyy")]
Converts the structure to the list of the keys.
>>>
keys (HashMap.fromList [('a', "xxx"), ('b', "yyy")])
"ab"
elems :: t -> [Val t] Source #
Converts the structure to the list of the values.
>>>
elems (HashMap.fromList [('a', "xxx"), ('b', "yyy")])
["xxx", "yyy"]
class ToList t => Container t where Source #
type ElementConstraint t :: * -> Constraint Source #
Constraint for elements. This can be used to implement more efficient implementation of some methods.
foldr :: (Element t -> b -> b) -> b -> t -> b Source #
foldr :: (Foldable f, t ~ f a, Element t ~ a) => (Element t -> b -> b) -> b -> t -> b Source #
foldl :: (b -> Element t -> b) -> b -> t -> b Source #
foldl :: (Foldable f, t ~ f a, Element t ~ a) => (b -> Element t -> b) -> b -> t -> b Source #
foldl' :: (Element t -> b -> b) -> b -> t -> b Source #
foldl' :: (Foldable f, t ~ f a, Element t ~ a) => (Element t -> b -> b) -> b -> t -> b Source #
length :: (Foldable f, t ~ f a, Element t ~ a) => t -> Int Source #
elem :: ElementConstraint t (Element t) => Element t -> t -> Bool Source #
elem :: (Foldable f, t ~ f a, Element t ~ a, ElementConstraint t ~ Eq, ElementConstraint t (Element t)) => Element t -> t -> Bool Source #
maximum :: Ord (Element t) => t -> Element t Source #
maximum :: (Foldable f, t ~ f a, Element t ~ a, Ord (Element t)) => t -> Element t Source #
minimum :: Ord (Element t) => t -> Element t Source #
minimum :: (Foldable f, t ~ f a, Element t ~ a, Ord (Element t)) => t -> Element t Source #
foldMap :: Monoid m => (Element t -> m) -> t -> m Source #
fold :: Monoid (Element t) => t -> Element t Source #
foldr' :: (Element t -> b -> b) -> b -> t -> b Source #
foldr1 :: (Element t -> Element t -> Element t) -> t -> Element t Source #
foldl1 :: (Element t -> Element t -> Element t) -> t -> Element t Source #
notElem :: ElementConstraint t (Element t) => Element t -> t -> Bool Source #
all :: (Element t -> Bool) -> t -> Bool Source #
any :: (Element t -> Bool) -> t -> Bool Source #
and :: Element t ~ Bool => t -> Bool Source #
or :: Element t ~ Bool => t -> Bool Source #
find :: (Element t -> Bool) -> t -> Maybe (Element t) Source #
Container ByteString Source # | |
Container ByteString Source # | |
Container IntSet Source # | |
Container Text Source # | |
Container Text Source # | |
Container [a] Source # | |
TypeError Constraint (DisallowInstance "Maybe") => Container (Maybe a) Source # | |
Container (NonEmpty a) Source # | |
Container (ZipList a) Source # | |
TypeError Constraint (DisallowInstance "Identity") => Container (Identity a) Source # | |
Container (Dual a) Source # | |
Container (Sum a) Source # | |
Container (Product a) Source # | |
Container (First a) Source # | |
Container (Last a) Source # | |
Container (IntMap v) Source # | |
Container (Seq a) Source # | |
Container (Set v) Source # | |
Container (HashSet v) Source # | |
Container (Vector a) Source # | |
TypeError Constraint (DisallowInstance "Either") => Container (Either a b) Source # | |
TypeError Constraint (DisallowInstance "tuples") => Container (a, b) Source # | |
Container (Map k v) Source # | |
Container (HashMap k v) Source # | |
Container (Const * a b) Source # | |
sum :: (Container t, Num (Element t)) => t -> Element t Source #
Stricter version of sum
.
>>>
sum [1..10]
55>>>
sum (Just 3)
<interactive>:43:1: error: • Do not use 'Foldable' methods on Maybe • In the expression: sum (Just 3) In an equation for ‘it’: it = sum (Just 3)
product :: (Container t, Num (Element t)) => t -> Element t Source #
Stricter version of product
.
>>>
product [1..10]
3628800>>>
product (Right 3)
<interactive>:45:1: error: • Do not use 'Foldable' methods on Either • In the expression: product (Right 3) In an equation for ‘it’: it = product (Right 3)
sequenceA_ :: (Container t, Applicative f, Element t ~ f a) => t -> f () Source #
Constrained to Container
version of sequenceA_
.
Others
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")]
One ByteString Source # | |
One ByteString Source # | |
One IntSet Source # | |
One Text Source # | |
One Text Source # | |
One [a] Source # | |
One (NonEmpty a) Source # | |
One (IntMap v) Source # | |
One (Seq a) Source # | |
One (Set v) Source # | |
Hashable v => One (HashSet v) Source # | |
Unbox a => One (Vector a) Source # | |
Storable a => One (Vector a) Source # | |
Prim a => One (Vector a) Source # | |
One (Vector a) Source # | |
One (Map k v) Source # | |
Hashable k => One (HashMap k v) Source # | |