on package:relude

on b u x y runs the binary function b on the results of applying unary function u to two arguments x and y. From the opposite perspective, it transforms two inputs and combines the outputs.
((+) `on` f) x y = f x + f y
Typical usage: sortBy (compare `on` fst). Algebraic properties:
  • (*) `on` id = (*) -- (if (*) ∉ {⊥, const
    ⊥})
  • ((*) `on` f) `on` g = (*) `on` (f . g)
  • flip on f . flip on g = flip on (g .
    f)
Create a list, map, Text, etc from a single element.
One is a typeclass for creating structures from a singleton element. It has three main goals:
  1. Give a shorter name for the construction: uses one instead of common singleton.
  2. Work with monomorphic structures like Text or IntSet.
  3. Give a clearer and less scary name for cases where you can use pure or (:[]).
Typeclass for data types that can be created from one element. E.g. lists, non-empty containers, maps.
>>> one True :: [Bool]
[True]

>>> one 'a' :: Text
"a"

>>> one (3, "hello") :: HashMap Int String
fromList [(3,"hello")]
Laws:
  • single-size: ∀ x . size (one x) ≡ 1
(where size is a specific function for each container that returns the size of this container)
A handler for a decoding error.
Function type for handling a coding error. It is supplied with two inputs:
  • A String that describes the error.
  • The input value that caused the error. If the error arose because the end of input was reached or could not be identified precisely, this value will be Nothing.
If the handler returns a value wrapped with Just, that value will be used in the output as the replacement for the invalid input. If it returns Nothing, no value will be used in the output. Should the handler need to abort processing, it should use error or throw an exception (preferably a UnicodeException). It may use the description provided to construct a more helpful error report.
The Const functor.
One or none. It is useful for modelling any computation that is allowed to fail.

Examples

Using the Alternative instance of Control.Monad.Except, the following functions:
>>> import Control.Monad.Except
>>> canFail = throwError "it failed" :: Except String Int

>>> final = return 42                :: Except String Int
Can be combined by allowing the first function to fail:
>>> runExcept $ canFail *> final
Left "it failed"

>>> runExcept $ optional canFail *> final
Right 42
The kind of constraints, like Show a
This module exports all container-related stuff.
Like universe, but returns NonEmpty list of some enumeration
>>> universeNonEmpty :: NonEmpty Bool
False :| [True]
>>> universeNonEmpty @Ordering
LT :| [EQ,GT]
>>> data TrafficLight = Red | Blue | Green deriving (Show, Eq, Enum, Bounded)

>>> universeNonEmpty :: NonEmpty TrafficLight
Red :| [Blue,Green]
>>> data Singleton = Singleton deriving (Show, Eq, Enum, Bounded)

>>> universeNonEmpty @Singleton
Singleton :| []
Re-exports most useful functionality from the Control.Exception module. Also provides some convenient utilities to throw and handle exceptions.
Any type that you wish to throw or catch as an exception must be an instance of the Exception class. The simplest case is a new exception type directly below the root:
data MyException = ThisException | ThatException
deriving Show

instance Exception MyException
The default method definitions in the Exception class do what we need in this case. You can now throw and catch ThisException and ThatException as exceptions:
*Main> throw ThisException `catch` \e -> putStrLn ("Caught " ++ show (e :: MyException))
Caught ThisException
In more complicated examples, you may wish to define a whole hierarchy of exceptions:
---------------------------------------------------------------------
-- Make the root exception type for all the exceptions in a compiler

data SomeCompilerException = forall e . Exception e => SomeCompilerException e

instance Show SomeCompilerException where
show (SomeCompilerException e) = show e

instance Exception SomeCompilerException

compilerExceptionToException :: Exception e => e -> SomeException
compilerExceptionToException = toException . SomeCompilerException

compilerExceptionFromException :: Exception e => SomeException -> Maybe e
compilerExceptionFromException x = do
SomeCompilerException a <- fromException x
cast a

---------------------------------------------------------------------
-- Make a subhierarchy for exceptions in the frontend of the compiler

data SomeFrontendException = forall e . Exception e => SomeFrontendException e

instance Show SomeFrontendException where
show (SomeFrontendException e) = show e

instance Exception SomeFrontendException where
toException = compilerExceptionToException
fromException = compilerExceptionFromException

frontendExceptionToException :: Exception e => e -> SomeException
frontendExceptionToException = toException . SomeFrontendException

frontendExceptionFromException :: Exception e => SomeException -> Maybe e
frontendExceptionFromException x = do
SomeFrontendException a <- fromException x
cast a

---------------------------------------------------------------------
-- Make an exception type for a particular frontend compiler exception

data MismatchedParentheses = MismatchedParentheses
deriving Show

instance Exception MismatchedParentheses where
toException   = frontendExceptionToException
fromException = frontendExceptionFromException
We can now catch a MismatchedParentheses exception as MismatchedParentheses, SomeFrontendException or SomeCompilerException, but not other types, e.g. IOException:
*Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: MismatchedParentheses))
Caught MismatchedParentheses
*Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: SomeFrontendException))
Caught MismatchedParentheses
*Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: SomeCompilerException))
Caught MismatchedParentheses
*Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: IOException))
*** Exception: MismatchedParentheses
The SomeException type is the root of the exception type hierarchy. When an exception of type e is thrown, behind the scenes it is encapsulated in a SomeException.
Render this exception value in a human-friendly manner. Default implementation: show.
Short for fmap . second.
>>> secondF length  $ Just (False, ['a', 'b'])
Just (False,2)
The largest element of a non-empty data structure with respect to the given comparison function.
>>> maximumOn1 abs (0 :| [2, 1, -3, -2])
-3
The smallest element of a non-empty data structure with respect to the given comparison function.
>>> minimumOn1 abs (0 :| [2, 1, -3, -2])
0
Convert a non-empty data structure to a NonEmpty list.
>>> toNonEmpty (Identity 2)
2 :| []
Similar to groupBy but keeps only one element as value.
>>> groupOneBy even [1 .. 6] :: HashMap Bool Int
fromList [(False,1),(True,2)]