| Copyright | (c) Justin Le 2018 |
|---|---|
| License | BSD3 |
| Maintainer | justin@jle.im |
| Stability | experimental |
| Portability | non-portable |
| Safe Haskell | None |
| Language | Haskell2010 |
Data.Containers.NonEmpty
Description
Non-Empty Typeclass
Provides the typeclass HasNonEmpty, which abstracts over different
types which have a "non-empty" variant.
Used to convert between and in between possibly-empty and non-empty
types. Instances are provided for all modules in this package, as well
as for NonEmpty in base and NonEmptyVector.
Synopsis
- class HasNonEmpty s where
- type NE s = t | t -> s
- nonEmpty :: s -> Maybe (NE s)
- fromNonEmpty :: NE s -> s
- withNonEmpty :: r -> (NE s -> r) -> s -> r
- empty :: s
- isEmpty :: s -> Bool
- unsafeToNonEmpty :: s -> NE s
- pattern IsNonEmpty :: HasNonEmpty s => NE s -> s
- pattern IsEmpty :: HasNonEmpty s => s
- overNonEmpty :: (HasNonEmpty s, HasNonEmpty t) => (NE s -> NE t) -> s -> t
- onNonEmpty :: HasNonEmpty s => (NE s -> r) -> s -> Maybe r
Documentation
class HasNonEmpty s where Source #
If s is an instance of HasNonEmpty, it means that there is
a corresponding "non-empty" version of s, .NE s
In order for things to be well-behaved, we expect that nonEmpty and
maybe should form an isomorphism (or that
empty fromNonEmpty. In addition,
the following properties should hold for most exectations:withNonEmpty empty fromNonEmpty == id
(x == empty) ==> isEmpty x
(x == empty) ==> isNothing (nonEmpty x)
isEmpty x ==> isNothing (nonEmpty x)
unsafeToNonEmpty x == fromJust (nonEmpty x)
- Usually,
not (isEmpty x) ==> isJust (nonEmpty x), but this isn't necessary.
Minimal complete definition
Methods
nonEmpty :: s -> Maybe (NE s) Source #
"Smart constructor" for given a (potentailly empty) NE ss.
Will return Nothing if the s was empty, and if the
Just ns was not empty, with n :: .NE s
Should form an isomorphism with .maybe empty fromNonEmpty
fromNonEmpty :: NE s -> s Source #
Convert a (non-empty NE ss) back into an s, "obscuring"
its non-emptiness from its type.
withNonEmpty :: r -> (NE s -> r) -> s -> r Source #
Continuation-based version of nonEmpty, which can be more
efficient in certain situations.
should be withNonEmpty empty fromNonEmptyid.
An empty s.
Check if an s is empty.
unsafeToNonEmpty :: s -> NE s Source #
Unsafely coerce an s into an (non-empty NE ss). Is
undefined (throws a runtime exception when evaluation is attempted)
when the s is empty.
Instances
| HasNonEmpty IntSet Source # | |
Defined in Data.Containers.NonEmpty | |
| HasNonEmpty [a] Source # | |
Defined in Data.Containers.NonEmpty | |
| HasNonEmpty (IntMap a) Source # | |
Defined in Data.Containers.NonEmpty | |
| HasNonEmpty (Seq a) Source # | |
Defined in Data.Containers.NonEmpty | |
| HasNonEmpty (Set a) Source # | |
Defined in Data.Containers.NonEmpty | |
| HasNonEmpty (Vector a) Source # | |
Defined in Data.Containers.NonEmpty | |
| HasNonEmpty (Map k a) Source # | |
Defined in Data.Containers.NonEmpty | |
pattern IsNonEmpty :: HasNonEmpty s => NE s -> s Source #
The IsNonEmpty and IsEmpty patterns allow you to treat a s as
if it were either a (where IsNonEmpty nn is a non-empty version
of s, type ) or an NE sIsEmpty.
For example, you can pattern match on a list to get a NonEmpty
(non-empty list):
safeHead :: [Int] -> Int safeHead (IsNonEmpty(x :| _)) = x -- here, the list was not empty safeheadIsEmpty= 0 -- here, the list was empty
Matching on means that the original input was not
empty, and you have a verified-non-empty IsNonEmpty nn :: to use.NE s
Note that because of the way coverage checking works for polymorphic
pattern synonyms, you will unfortunatelly still get incomplete pattern
match warnings if you match on both IsNonEmpty and NonEmpty, even
though the two are meant to provide complete coverage. However, many
instances of HasNonEmpty (like NEMap, NEIntMap, NESet,
NEIntSet) will provide their own monomorphic versions of these
patterns that can be verified as complete covers by GHC.
This is a bidirectional pattern, so you can use IsNonEmpty to convert
a back into an NE ss, "obscuring" its non-emptiness (see
fromNonEmpty).
pattern IsEmpty :: HasNonEmpty s => s Source #
The IsNonEmpty and IsEmpty patterns allow you to treat a s as
if it were either a (where IsNonEmpty nn is a non-empty version
of s, type ) or an NE sIsEmpty.
Matching on IsEmpty means that the original item was empty.
This is a bidirectional pattern, so you can use IsEmpty as an
expression, and it will be interpreted as empty.
Note that because of the way coverage checking works for polymorphic
pattern synonyms, you will unfortunatelly still get incomplete pattern
match warnings if you match on both IsNonEmpty and NonEmpty, even
though the two are meant to provide complete coverage. However, many
instances of HasNonEmpty (like NEMap, NEIntMap, NESet,
NEIntSet) will provide their own monomorphic versions of these
patterns that can be verified as complete covers by GHC.
See IsNonEmpty for more information.
overNonEmpty :: (HasNonEmpty s, HasNonEmpty t) => (NE s -> NE t) -> s -> t Source #
Useful function for mapping over the "non-empty" representation of a type.
Since: 0.3.3.0
onNonEmpty :: HasNonEmpty s => (NE s -> r) -> s -> Maybe r Source #
Useful function for applying a function on the "non-empty" representation of a type.
If you want a continuation taking , you can
use NE s -> 'Maybe r'.withNonEmpty Nothing
Since: 0.3.3.0