optional-args-1.0.2: Optional function arguments

Safe HaskellSafe
LanguageHaskell2010

Data.Optional

Contents

Description

Use the Optional type for optional function arguments. For example:

import Data.Optional

greet :: Optional String -> String
greet (Specific name) = "Hello, " ++ name
greet  Default        = "Hello"
>>> greet (Specific "John")
"Hello, John"
>>> greet Default
"Hello"

The Optional type overloads as many Haskell literals as possible so that you do not need to wrap values in Specific. For example, if you enable the OverloadedStrings extension you can use a naked string literal instead:

>>> :set -XOverloadedStrings
>>> greet "John"
"Hello, John"

The Optional type also implements Num and Fractional, so you can use numeric literals in place of Optional values:

birthday :: Optional Int -> String
birthday (Specific age) = "You are " ++ show age ++ " years old!"
birthday  Default       = "You are one year older!"
>>> birthday 20
"You are 20 years old!"
>>> birthday Default
"You are one year older!"

The IsString, Num, and Fractional instances are recursive, so you can wrap your types in a more descriptive newtype and derive IsString, Num or Fractional:

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

import Data.Optional
import Data.String (IsString)

newtype Name = Name { getName :: String } deriving (IsString)

greet :: Optional Name -> String
greet (Specific name) = "Hello, " ++ getName name
greet  Default        = "Hello"

newtype Age = Age { getAge :: Int } deriving (Num)

birthday :: Optional Age -> String
birthday (Specific age) = "You are " ++ show (getAge age) ++ " years old!"
birthday  Default       = "You are one year older!"

... and you would still be able to provide naked numeric or string literals:

>>> :set -XOverloadedStrings
>>> greet "John"
"Hello, John"
>>> birthday 20
"You are 20 years old!"

You can use empty as a short-hand for a Default argument:

>>> greet empty
"Hello"
>>> birthday empty
"You are one year older!"

You can also use pure as a short-hand for a Specific argument:

>>> greet (pure "John")
"Hello, John"
>>> birthday (pure 20)
"You are 20 years old!"

Synopsis

Optional

data Optional a Source #

A function argument that has a Default value

Constructors

Default 
Specific a 

Instances

Monad Optional Source # 

Methods

(>>=) :: Optional a -> (a -> Optional b) -> Optional b #

(>>) :: Optional a -> Optional b -> Optional b #

return :: a -> Optional a #

fail :: String -> Optional a #

Functor Optional Source # 

Methods

fmap :: (a -> b) -> Optional a -> Optional b #

(<$) :: a -> Optional b -> Optional a #

Applicative Optional Source # 

Methods

pure :: a -> Optional a #

(<*>) :: Optional (a -> b) -> Optional a -> Optional b #

liftA2 :: (a -> b -> c) -> Optional a -> Optional b -> Optional c #

(*>) :: Optional a -> Optional b -> Optional b #

(<*) :: Optional a -> Optional b -> Optional a #

Foldable Optional Source # 

Methods

fold :: Monoid m => Optional m -> m #

foldMap :: Monoid m => (a -> m) -> Optional a -> m #

foldr :: (a -> b -> b) -> b -> Optional a -> b #

foldr' :: (a -> b -> b) -> b -> Optional a -> b #

foldl :: (b -> a -> b) -> b -> Optional a -> b #

foldl' :: (b -> a -> b) -> b -> Optional a -> b #

foldr1 :: (a -> a -> a) -> Optional a -> a #

foldl1 :: (a -> a -> a) -> Optional a -> a #

toList :: Optional a -> [a] #

null :: Optional a -> Bool #

length :: Optional a -> Int #

elem :: Eq a => a -> Optional a -> Bool #

maximum :: Ord a => Optional a -> a #

minimum :: Ord a => Optional a -> a #

sum :: Num a => Optional a -> a #

product :: Num a => Optional a -> a #

Traversable Optional Source # 

Methods

traverse :: Applicative f => (a -> f b) -> Optional a -> f (Optional b) #

sequenceA :: Applicative f => Optional (f a) -> f (Optional a) #

mapM :: Monad m => (a -> m b) -> Optional a -> m (Optional b) #

sequence :: Monad m => Optional (m a) -> m (Optional a) #

Alternative Optional Source # 

Methods

empty :: Optional a #

(<|>) :: Optional a -> Optional a -> Optional a #

some :: Optional a -> Optional [a] #

many :: Optional a -> Optional [a] #

MonadPlus Optional Source # 

Methods

mzero :: Optional a #

mplus :: Optional a -> Optional a -> Optional a #

Eq a => Eq (Optional a) Source # 

Methods

(==) :: Optional a -> Optional a -> Bool #

(/=) :: Optional a -> Optional a -> Bool #

Fractional a => Fractional (Optional a) Source # 
Num a => Num (Optional a) Source # 
Show a => Show (Optional a) Source # 

Methods

showsPrec :: Int -> Optional a -> ShowS #

show :: Optional a -> String #

showList :: [Optional a] -> ShowS #

IsString a => IsString (Optional a) Source # 

Methods

fromString :: String -> Optional a #

Semigroup a => Semigroup (Optional a) Source # 

Methods

(<>) :: Optional a -> Optional a -> Optional a #

sconcat :: NonEmpty (Optional a) -> Optional a #

stimes :: Integral b => b -> Optional a -> Optional a #

Monoid a => Monoid (Optional a) Source # 

Methods

mempty :: Optional a #

mappend :: Optional a -> Optional a -> Optional a #

mconcat :: [Optional a] -> Optional a #

defaultTo :: a -> Optional a -> a Source #

The defaultTo function takes a default value and an Optional value. If the Optional is Default, it returns the default value; otherwise, it returns the value contained in the Optional.

fromOptional :: Alternative f => Optional a -> f a Source #

Convert an Optional value into an instance of Alternative.

optional :: b -> (a -> b) -> Optional a -> b Source #

The optional function takes a default value, a function, and an Optional value. If the Optional value is Default, the function returns the default value. Otherwise, it applies the function to the value inside the Optional and returns the result.

Re-exports

empty :: Alternative f => forall a. f a #

The identity of <|>

pure :: Applicative f => forall a. a -> f a #

Lift a value.