Copyright | (c) Sophie Hirn 2018 |
---|---|
License | BSD2 |
Maintainer | sophie.hirn@wyvernscale.com |
Safe Haskell | Safe |
Language | Haskell2010 |
Some helpers to make using Prelude.filter and similar value selection a bit easier. Includes combinators for predicates as well as an operator to match the constructor used for the given value.
- constrName :: (HasConstructor (Rep a), Generic a) => a -> String
- class HasConstructor (f :: * -> *) where
- class ReduceWith a where
- class (HasConstructor (Rep c), Generic c) => Reduce a c | a -> c where
- (=?=) :: (Reduce a c, Reduce b c) => a -> b -> Bool
- (==>) :: (a -> Bool) -> (a -> b) -> a -> Maybe b
- (<||>) :: (a -> Bool) -> (a -> Bool) -> a -> Bool
- any_ :: [a -> Bool] -> a -> Bool
- (<&&>) :: (a -> Bool) -> (a -> Bool) -> a -> Bool
- all_ :: [a -> Bool] -> a -> Bool
- data Infinite a
- mapMaybe :: (a -> Maybe b) -> [a] -> [b]
Constructors
The (=?=)
-operator can be used to check whether two values were
generated using the same constructor. For this to work, the
underlying data type must instantiate Generic
,
parameters to the constructor can additionally be left out if their
type implements ReduceWith
.
constrName :: (HasConstructor (Rep a), Generic a) => a -> String Source #
Retrieve the constructor name of the given value as a string. This implementation is taken from https://stackoverflow.com/questions/48179380/getting-the-data-constructor-name-as-a-string-using-ghc-generics .
class HasConstructor (f :: * -> *) where Source #
Automatically derived from Generic
instances.
genericConstrName :: f x -> String Source #
(HasConstructor x, HasConstructor y) => HasConstructor ((:+:) * x y) Source # | |
HasConstructor f => HasConstructor (D1 * c f) Source # | |
Constructor Meta c => HasConstructor (C1 * c f) Source # | |
Reduction
Constructors can be reduced to values by passing them arbitrary
arguments. The actual value of those does not impact the result of
the (=?=)
-operator. For lazy members, passing undefined
works
just fine, but putting undefined
into strict fields causes carnage.
ReduceWith
provides arbitrary values, deriving from Default
where
possible.
class ReduceWith a where Source #
Type that can be reduced away from a constructor. Use this to make your
data types compatible. The reduction process and the (=?=)
-operator do
not evaluate fields, therefore creating an empty instance which defaults to
is okay as long as no reduced field of
this type is strict.reduceWith
= undefined
reduceWith :: a Source #
ReduceWith Bool Source # | |
ReduceWith Char Source # | |
Default a => ReduceWith a Source # | |
class (HasConstructor (Rep c), Generic c) => Reduce a c | a -> c where Source #
Reduction of a constructor a -> ... -> c
to a value of type c
.
Operators
(=?=) :: (Reduce a c, Reduce b c) => a -> b -> Bool infixl 4 Source #
Checks whether two values are created by the same data constructor. Also works with constructors that have not yet received all their arguments. This allows for very convenient constructs, e.g.:
>>>
Just 1 =?= Just
True
>>>
Just 1 =?= Nothing
False
>>>
let filterJust = filter (=?= Just)
>>>
filterJust [Just 1, Nothing, Just 9001]
[Just 1, Just 9001]
>>>
let filterJust_ = mapMaybe $ (=?= Just) ==> fromJust
>>>
filterJust_ [Just 1, Nothing, Just 9001]
[1, 9001]
>>>
let over9000 = mapMaybe $ ((=?= Just) <&&> (>9000) . fromJust) ==> fromJust
>>>
over9000 [Just 1, Nothing, Just 9001]
[9001]
Matching Wrappers
Adds negative and positive infinity to an ordered type. The fromEnum
function is inherently susceptible to overflow since the class Enum
is
defined using Int
instead of Integer
, but this should not cause trouble
with "small" enums.
Functor Infinite Source # | |
(Eq a, Bounded a, Enum a) => Enum (Infinite a) Source # | |
Eq a => Eq (Infinite a) Source # | |
Ord a => Ord (Infinite a) Source # | |
Read a => Read (Infinite a) Source # | |
Show a => Show (Infinite a) Source # | |
Generic (Infinite a) Source # | |
Default a => Default (Infinite a) Source # | |
type Rep (Infinite a) Source # | |
Useful functions from other modules
mapMaybe :: (a -> Maybe b) -> [a] -> [b] #
The mapMaybe
function is a version of map
which can throw
out elements. In particular, the functional argument returns
something of type
. If this is Maybe
bNothing
, no element
is added on to the result list. If it is
, then Just
bb
is
included in the result list.
Examples
Using
is a shortcut for mapMaybe
f x
in most cases:catMaybes
$ map
f x
>>>
import Text.Read ( readMaybe )
>>>
let readMaybeInt = readMaybe :: String -> Maybe Int
>>>
mapMaybe readMaybeInt ["1", "Foo", "3"]
[1,3]>>>
catMaybes $ map readMaybeInt ["1", "Foo", "3"]
[1,3]
If we map the Just
constructor, the entire list should be returned:
>>>
mapMaybe Just [1,2,3]
[1,2,3]